举一个中缀表达式的例子:a+b-a*((c+d)/e-f)+g
一、中缀表达式转后缀表达式
方法一:括号法
比较简单方便。
①按照运算符的优先级,对所有的运算单位加括号。
于是变成:(((a+b)-(a*(((c+d)/e)-f)))+g)
②从最里面的括号开始,依次把运算符号移动到对应的括号的后面。
于是变成:(((ab)+(a(((cd)+e)/f)-)*)-g)+
③最后,把括号都去掉
于是变成:ab+acd+e/f-*-g+
方法二:利用语法树
略。
方法三:基于堆栈的算法
具体转换方式:
从左到右进行遍历。
1.遇到的是运算数,直接输出。
2.遇到的是左括号'(',直接压入堆栈(括号是最高优先级,无需比较;入栈后优先级降到最低,确保其他符号正常入栈)。
3.遇到的是右括号')',意味着括号已结束。不断弹出栈顶运算符并输出,直到遇到左括号,这个左括号弹出但是不输出。
4.遇到的是运算符('+'、'-'、'*'、'/'),有三种情况
①如果栈为空,直接入栈。
②如果栈顶元素是左括号'(',直接入栈。
③如果栈顶元素是运算符,则需要进行比较,
1-如果优先级大于栈顶运算符,则压入堆栈;
2-如果优先级小于等于栈顶运算符,则将栈顶运算符弹出并输出,然后比较新的栈顶运算符,直到优先级大于栈顶运算符或者栈空,再将该运算符入栈
5.如果对象处理完毕,则按顺序弹出并输出栈中所有运算符
算法如下:
/*
中缀转后缀
思路:
中缀存于一个字符数组infix[]里,有一个辅助栈s1,栈顶元素为top1,有一个结果栈s2,栈顶元素为top2。
从左向右扫描。i=0,当infix[i]!='\0'时,
1、碰到'0'-'9',存入s2中。
2、碰到'(',存入s1中。
3、碰到'+'、'-'、'*'、'/',
如果栈为空,或者top1='(',或者运算符的优先级大于top1栈顶元素的优先级,存入s1中;否则s2[++top2]=s1[top1--]。
4、碰到')',将s1里截止到'('以前的元素全部放到s2中,并把'('丢掉
*/
//判断运算符的优先级
int getPriority(char op){
if(op=='+'||op=='-')
return 0; //+或-的优先级比较低
else
return 1;
}
void infixToPostFix(char infix[], char s2[], int &top2) //infix[]是中缀表达式存在数组里,s2是结果栈
{
char s1[maxSize]; int top1=-1; //s1是辅助栈
int i=0;
while(infix[i]!='\0'){
if('0'<=infix[i]&&infix[i]<='9'){ //如果扫描到'0'-'9'字符,将它放入s2
s2[++top2]==infix[i];
++i;
}
else if(infix[i]=='('){ //如果扫描到'(',将它放入s1
s1[++top1]='(';
++i;
}
else if(infix[i]=='+'|| //如果扫描到'+','-','*','/'字符,需要和s1里的元素进行判断
infix[i]=='-'||
infix[i]=='*'||
infix[i]=='/'){
if(top1==-1|| //判断s1是否为空
s1[top1]=='('|| //判断辅助栈的栈顶元素是否为'('
getPriority(infix[i])>getPriority(top1[top1])){ //判断表达式里元素的优先级是否大于s1元素的优先级
s1[++top1]=infix[i];
++i;
}
else //如果不是,将辅助站的运算符放入结果栈里
s2[++top2]==s1[top1--];
}
else if(infix[i]==')'){
while(s1[top1]!='(')
s2[++top2]=s1[top1--];
--top1; //删除s1里的'('
++i;
}
}
while(top1!=-1)
s2[++top2]=s1[top1--]; //将s1中的元素都放入s2
}
二、中缀表达式转前缀表达式
和中缀表达式转后缀表达式类似,稍微有点区别。
方法一:括号法
比较简单方便。
①按照运算符的优先级,对所有的运算单位加括号。
于是变成:(((a+b)-(a*(((c+d)/e)-f)))+g)
②从最里面的括号开始,依次把运算符号移动到对应的括号的前面。
于是变成:+(-(+(ab)*(a-(/(+(cd)e)f)))g)
③最后,把括号都去掉
于是变成:+-+ab*a-/+cdefg
方法二:利用语法树
略。
方法三:基于堆栈的算法
具体转换方式:
从右到左进行遍历。
1.遇到的是运算数,直接输出。
2.遇到的是右括号')',直接压入堆栈(括号是最高优先级,无需比较;入栈后优先级降到最低,确保其他符号正常入栈)。
3.遇到的是左括号'(',意味着括号已结束。不断弹出栈顶运算符并输出,直到遇到右括号,这个右括号弹出但是不输出。
4.遇到的是运算符('+'、'-'、'*'、'/'),有三种情况
①如果栈为空,直接入栈。
②如果栈顶元素是右括号')',直接入栈。
③如果栈顶元素是运算符,则需要进行比较,
1-如果优先级大于等于栈顶运算符,则压入堆栈;
2-如果优先级小于栈顶运算符,则将栈顶运算符弹出并输出,然后比较新的栈顶运算符,直到优先级大于等于栈顶运算符或者栈空,再将该运算符入栈
5.如果对象处理完毕,则按顺序弹出并输出栈中所有运算符
算法如下:
/*
中缀转前缀
思路:
中缀存于一个字符数组infix[]里,有一个辅助栈s1,栈顶元素为top1,有一个结果栈s2,栈顶元素为top2。
从右向左扫描。i=len-1,当i>=0时,
1、碰到'0'-'9',存入s2中。
2、碰到')',存入s1中。
3、碰到'+'、'-'、'*'、'/',
如果栈为空,或者top1=')',运算符的优先级大于等于top1栈顶元素的优先级,存入s1中;否则s2[++top2]=s1[top1--]。
4、碰到'(',将s1里截止到')'以前的元素全部放到s2中,并把')'丢掉
*/
//判断运算符的优先级
int getPriority(char op){
if(op=='+'||op=='-')
return 0; //+或-的优先级比较低
else
return 1;
}
void infixToPreFix(char infix[], int len, char s2[], int top2){
char s1[maxSize]; int top1=-1;
int i=len-1;
while(i>=0){
if('0'<=infix[i]&&infix[i]<='9'){
s2[++top2]=infix[i];
--i;
}
else if(infix[i]==')'){
s1[++top1]=')';
--i;
}
else if(infix[i]=='+'||
infix[i]=='-'||
infix[i]=='*'||
infix[i]=='/'){
if(top1==-1||
s1[top1]==')'||
getPriority(infix[i])>=getPriority(s1[top1])){
s1[++top1]=infix[i];
--i;
}
else
s2[++top2]=s1[top1--];
}
if(infix[i]=='('){
while(s1[top1]!=')')
s2[++top2]=s1[top1--];
--top1;
--i;
}
}
while(top1!=-1)
s2[++top2]=s1[top1--];
}