练习题————剔除多余括号
题目描述
输入一个含有括号的四则运算表达式,要求去掉可能含有的多余的括号,结果要保持原表达式中变量和运算符的相对位置不变,且与原表达式等价,不要求化简。另外不考虑'+'
'-'用作正负号的情况,即输入表达式不会出现(+a)或(-a)的情形。
输入
第1行:一个字符串表示要整理的表达式
输出
第1行:整理后的结果
样例输入
(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
((a+b)*f)-(i/j)
样例输出
(a+b)*f-i/j
提示
输入:
1. a+(b+c)-d
2. a+b/(c+d)
3. (a*b)+c/d
4. ((a+b)*f)-(i/j)
输出:
1. a+b+c-d
2. a+b/(c+d)
3. a*b+c/d
4. (a+b)*f-i/j
一个半小时的青春年华,因此题,付诸东流/(ㄒoㄒ)/~~、
不要说其中的心路历程,直接说这道题吧
首先,在输入合法的情况下,括号两旁一定是运算符号,括号拆不拆取决于括号中等级最小的运算符是否不小于两边符号
小心!a-(b-c)之类的不能拆!!
所以,将每个括号中等级最小的符号存储下来,进行比较后在决定最终是否删除
不说了,代码如下:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct ill{
int l,r,mi;
bool no;
}h[50001];
char a[100001];
int l,g;
int work(int s)
{
int i;
h[++g].l=s;
h[g].mi=5;
int x=g;
for(i=s+1;i<=l;i++)
{
if(a[i]=='(')i=work(i)+1;
if(a[i]==')'){h[x].r=i;return i;}
if(a[i]=='+')h[x].mi=min(h[x].mi,1);
if(a[i]=='-')h[x].mi=min(h[x].mi,2);
if(a[i]=='*')h[x].mi=min(h[x].mi,3);
if(a[i]=='/')h[x].mi=min(h[x].mi,4);
}
h[x].r=l;
return i;
}
void del(int x)
{
int i;
for(i=h[x].l+1;i<h[x].r;i++)
a[i-1]=a[i];
for(i=h[x].r+1;i<=l;i++)
a[i-2]=a[i];
l-=2;
}
int main()
{
scanf("%s",a+1);
l=strlen(a+1);
int i=work(0);
for(i=2;i<=g;i++)
{
int x=h[i].l-1,y=h[i].r+1;
int xma=0,yma=0;
if(a[x]=='+')xma=max(xma,1);
if(a[x]=='-')xma=max(xma,2);
if(a[x]=='*')xma=max(xma,3);
if(a[x]=='/')xma=max(xma,4);
if(a[y]=='+')yma=max(yma,1);
if(a[y]=='-')yma=max(yma,2);
if(a[y]=='*')yma=max(yma,3);
if(a[y]=='/')yma=max(yma,4);
if(yma<=h[i].mi)
{
if((xma==2||xma==4)&&xma<h[i].mi)
h[i].no=1;
if((xma==1||xma==3||xma==0)&&xma<=h[i].mi)
h[i].no=1;
}
}
for(i=2;i<=g;i++)
if(h[i].no)
a[h[i].l]=a[h[i].r]=0;
for(i=1;i<=l;i++)
if(a[i])
printf("%c",a[i]);
}