蓝桥杯

来源:互联网 发布:简述liunx下的串口编程 编辑:程序博客网 时间:2024/05/14 04:00
算法训练 删除多余括号
题目:(蓝桥杯第四组测试数据有问题最高分85分 )
问题描述
  从键盘输入一个含有括号的四则运算表达式,要求去掉可能含有的多余的括号,结果要保持原表达式中变量和运算符的相对位置不变,且与原表达式等价,不要求化简。另外不考虑'+'  '-'用作正负号的情况,即输入表达式不会出现(+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位乘除加减。括号内为1外1去括号,括号内为1外2不去括号,括号内为2外1去括号,括号内为2外2去括号。(注意,这里的内的符号不包括嵌套括号里面的符号)

括号嵌套:控制循环判断的下标。(代码有注释很清楚)

代码在此:
#include<stdio.h>#include<string.h>#define SIZE 256//最大字符串 #define REC 10//如果该括号需要删除就标记为REC char a[SIZE];//存储字符串 int len;//字符串长度 int judge (int k) {int outGrade = 0;//括号两边外的符号: 0 说明左右没符号; 运算等级1左右只是加减;运算等级2左右至少有一个乘除int inGrade = 0;//两边括号内部的符号 (部包括内嵌括号里的符号) : 运算等级1只有加减,运算等级2至少有一个乘除int num = 1;//标记i循环到第几层嵌套的括号  一开始只有一层 int i;int re = 0;//函数返回 (如果没内嵌括号返回右括号下标,如果有内嵌括号返回内嵌括号的左括号-1,因为函数返回到fun()的for语句会自增到左括号下标) int judge = 0;//标记记录最左边的内嵌括号做为返回 for(i = k+1; i < len && num > 0; i ++){//退出的条件是完全退出括号 if(a[i] == '('){//嵌多一层括号 num ++;if(judge == 0){re = i-1;judge = 1;}}if(num == 1){//需要计算第一层括号内的符号运算等级 if(inGrade == 0){if(a[i] == '+' || a[i] == '-')inGrade = 1;else if(a[i] == '*' || a[i] == '/')inGrade = 2;}if(inGrade == 1){if(a[i] == '*' || a[i] == '/')inGrade = 2;} }if(a[i] == ')'){//退出一层括号 num --;}}i --;//for退回指向有括号的下标 /*k 为左括号下标 i 为有括号下标 */outGrade = 0;if(k-1 > -1){//左边有符号 if(a[k-1] == '+' || a[k-1] == '-')outGrade = 1;elseoutGrade = 2;}if(outGrade == 0 || outGrade == 1){//运算阶级是否需要提高 if(i+1 < len){//右边有符号 if(a[i+1] == '+' || a[i+1] == '-')outGrade = 1;elseoutGrade = 2;}}//printf("%d\n%d %d\n", i, inGrade, outGrade);if(inGrade == 0){//内部没符号比如 2+5+()-2的情况 a[k] = REC;a[i] = REC;} else if(inGrade == 1){if(outGrade == 1){//内为1(加减),外为1 (加减)去括号 a[k] = REC;a[i] = REC;return i+1;} else {//内为1(加减),外为2 (加减)不去括号 ; }} else if(inGrade == 2){//内为2(加减),外为2或1 (加减)去括号 a[k] = REC;a[i] = REC;}if(re == 0)re = i;else ;return re;}void fun (int k) {int i;for(i = 0; i < len; i ++){if(a[i] != '('){;} else {//返回右括号的有下标 i = judge(i);//控制下标处理嵌套括号 }}}int main () {int i;gets(a);len = strlen(a);fun(0);for(i = 0; i < len; i ++){if(a[i] != REC)printf("%c", a[i]);}return 0;}


0 0
原创粉丝点击