蓝桥杯 算法训练 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 #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] != '\0') { 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] != '\0') { 87 if (exp[i] != ' ') 88 { 89 printf("%c", exp[i]); 90 } 91 } 92 93 return 0; 94 }