蓝桥杯 算法训练 ALGO-57 删除多余括号

算法训练 删除多余括号  
时间限制:1.0s   内存限制:512.0MB
问题描述
  从键盘输入一个含有括号的四则运算表达式,要求去掉可能含有的多余的括号,结果要保持原表达式中变量和运算符的相对位置不变,且与原表达式等价,不要求化简。另外不考虑'+' '-'用作正负号的情况,即输入表达式不会出现(+a)或(-a)的情形。
输入格式
  表达式字符串,长度不超过255,  并且不含空格字符。表达式中的所有变量都是单个小写的英文字母, 运算符只有加+减-乘*除/等运算符号。
输出格式
  去掉多余括号后的表达式
样例输入
样例一:
a+(b+c)-d
样例二:
a+b/(c+d)
样例三:
(a*b)+c/d
样例四:
((a+b)*f)-(i/j)

 样例输出样例一:

a+b+c-d
样例二:
a+b/(c+d)
样例三:
a*b+c/d
样例四:
(a+b)*f-i/j

题目解析:

  本道题其实化简表达式,这是我们小学学到的内容,即题目中写到:结果要保持原表达式中变量和运算符的相对位置不变,且与原表达式等价,不要求化简。

  遍历输入的表达式,如果发现左括号,则找到与它对应的右括号,并根据括号左右及中间内容分情况处理该括号是否可以删除。在递归地处理过程中,如果又发现了括号,则先处理发现的这个括号是否可以删除,处理结束后,返回上一个括号,继续递归处理,直至所有的括号处理完成。

  有以下几种情况括号是不可以删除的:

  1. 括号前边为 “ - ”,且括号中为 “ + ” 或 “ - ”,不能删除;
  2. 括号前边为 “ / ”,不能删除;
  3. 括号后为 “ * ”,且括号中为 “ + ” 或 “ - ”,不能删除;

  有以下几种情况是可以删除:

  1. 括号前和后为 “ + ” 或 “ - ”,括号中为 “ + ” 或 “ - ” 或 “ * ” 或 “ / ”,可以删除,但是注意:若括号前为 “ - ”,括号中为 “ + ” 或  “ - ”,在前边已经处理了,所以可以排除这种情况;
  2. 括号前为 “ * ”,括号中为 “ * ” 或 “ / ”,括号后为 “ + ” 或 “ - ” 或 “ * ” 或 “ / ”,可以删除;

  其他情况不能删除。

示例代码:

 1 #include<stdio.h>
 2 
 3 //检测括号是否可以删除 
 4 int check(char s[], int left, int right)
 5 {
 6     int i;            //下标 
 7     int leftCount;    //左括号统计 
 8     
 9     //处理 ' -(a +|- b) ' 
10     if (s[left-1] == '-')
11     {
12         i = left;
13         leftCount = 1;
14         while (++i < right) {
15             if (s[i] == '(')
16             {
17                 leftCount++;
18             }
19             else if ((s[i] == '+' || s[i] == '-' ) && leftCount == 1)
20             {
21                 return 0;
22             }
23         }
24     }
25     
26     //处理 ' /(a +|-|*|/ b) ' 
27     if (s[left-1] == '/')
28     {
29         return 0;
30     }
31     
32     //处理 ' +(a +|-|*|/ b) +|- ' 
33     if (s[left-1] != '*' && s[left-1] != '/' &&
34         s[right+1] != '*' && s[right+1] != '/')
35     {
36         return 1;
37     }
38     
39     //处理 ' *(a *|/ b) +|-|*|/ ' 
40     i = left;
41     leftCount = 1;
42     while (++i < right) {
43         if (s[i] == '(')
44         {
45             leftCount++;
46         }
47         else if ((s[i] == '*' || s[i] == '/' ) && leftCount == 1)
48         {
49             return 1;
50         }
51     }
52     return 0;
53 }
54 
55 //删除多余的括号 
56 int delExcessBrackets(char s[], int index)
57 {
58     int left, right;
59     while (s[index] != '') {
60         if (s[index] == ')')     //如果为右括号,返回下标 
61         {
62             return index;    
63         }
64         if (s[index] == '(')     //如果为左括号,找到右括号的下标 
65         {
66             left = index;
67             index = right =  delExcessBrackets(s, index+1);
68             
69             if (check(s, left, right))    //若检测结果为可以删除,那么把括号位置换成空 
70             {
71                 s[left] = s[right] = ' '; 
72             }
73         }
74         index++;
75     }        
76 } 
77 
78 int main()
79 {
80     char exp[256];
81     scanf("%s", exp);
82     
83     delExcessBrackets(exp, 0);
84     
85     int i = -1;
86     while (exp[++i] != '') {
87         if (exp[i] != ' ')
88         {
89             printf("%c", exp[i]);
90         }
91     }
92     
93     return 0;
94 }
原文地址:https://www.cnblogs.com/cao-lei/p/7236051.html