#includeusing namespace std;
char exp[100] = "(a*b)+c/d";//定义待处理的表达式
const int N = strlen(exp);//定义表达式的长度
const char DE = 'X';//若该括号需要删除则赋值为DE 注意一定是char类型的
void DeleteBracket(int k);
int Judge(int k);
int main ()
{
DeleteBracket(0);
for(int i = 0; i < N; i ++){
if(exp[i] != DE)
printf("%c", exp[i]);
}
return 0;
}
void DeleteBracket(int k)
{
for(int i = 0; i < N; i++)
{
if(exp[i] == '(')//返回右括号的有下标
i = Judge(i);//控制下标处理嵌套括号
//i是遇到的左括号的下标
}
}
int Judge(int k)//k是左括号的下标
{
int out = 0;
int in = 0;
int aspect = 1;
int re = 0;
int judge = 0;//标记记录最左边的内嵌括号做为返回
int i;//记录右括号的下标
for(i = k + 1; i < N && aspect > 0; i++)//退出的条件是表达式结束 或者完全退出括号
{
if(exp[i] == '(')//此时说明有两个左括号紧挨着
{
aspect++;//括号的层次数+1
if(judge == 0)
{
re = i - 1;//此时属于有内嵌括号的情况 因此返回内嵌括号的左括号-1 因为返回到Fun函数时for循环有自增操作 增加后的值为左括号的下标
judge = 1;
}
}
if(aspect == 1)//此时需要计算第一层括号内的运算等级
{
if(in == 0)
{
if(exp[i] == '+' || exp[i] == '-')//因为i=k+1 而k是左括号的下标 因此i是括号内的第一个元素
in = 1;//加减的优先级是1
else if(exp[i] == '*' || exp[i] == '/')
in = 2;
}
if(in == 1)
{
if(exp[i] == '*' || exp[i] == '/')
in = 2;
}
}
if(exp[i] == ')')
{
aspect--;//此时证明处理完一层括号 因此层次数-1 而后进入for循环的判断条件 表达式是否处理完毕或者括号处理完毕
}
}
i--;//for循环退出后 i是右括号的下标 将循环退出时多加的1减去
//此时k为左括号下标 i为右括号下标
if(k > 0)//此时证明左边有符号 因为表达式的下标从0开始 而k是左括号的下标 如果k>0则证明一定存在符号与左括号挨着
{//左括号左边一定是符号而不可能是数 因此可以直接用if-else语句判断
if(exp[k - 1] == '+' || exp[k - 1] == '-')
out = 1;
else
out = 2;
}
//判断out的运算等级是否要提高 i是右括号的下标
if(out == 0 || out == 1)
{
if(i + 1 < N)//判断右括号是否为表达式的结尾 如果不是 则右括号的右边一定是一个符号
{
if(exp[i + 1] == '+' || exp[i + 1] == '-')//与上面判断括号左侧的原理相同
out = 1;
else
out = 2;
}
}
//本算法中对括号的删除 是通过将该位置的元素赋予特殊值 在打印的时候加以区分 而没有真正的从数组中去除
if(in == 0)//括号内部无符号 为单个空括号的情况 2+5+()-2
{
exp[i] = DE;//当内部无符号的时候 该括号可以直接删除 ik分别为右括号的左括号的下标
exp[k] = DE;
}
else if(in == 1 && out == 1)
{
exp[i] = DE;//此时内外均为加减运算 因此可以直接将括号去除
exp[k] = DE;
return i + 1;//此时返回原右括号的下一个元素的下标 进行下一步的处理
}
else if(in == 2)
{
exp[i] = DE;//此时内为乘除运算 因此无论外部是什么均可以直接将括号去除
exp[k] = DE;
}
if(re == 0)//如果没内嵌括号返回右括号下标 如果有内嵌括号返回内嵌括号的左括号-1
//因为函数返回到Fun()的for语句会自增到左括号下标 继续下一步的处理
re = i;
return re;
}