题目描述:
涉及运算符有“+”、“-”、“*”、“/”、“(”、“)”,利用栈将输入的中缀表达式转换成等价的后缀表达式,并输出。
输入:
输入一个字符串表示的中缀表达式,其中每个操作数用一个小写字母表示。
输出:
将对应的后缀表达式输出。
算法:
1.遍历输入字符串,若遇到操作数,直接输出;
2.若遇到字符串,先判断栈是否为空,若为空,直接压入栈;若不为空,取栈顶元素 (1)若栈顶元素比操作符优先级高或相等,则将栈顶元素弹出并打印;
(2)若栈顶元素比操作符优先级低,则将操作符入栈
3.若遇到左括号,直接入栈;
4.若遇到右括号(右括号用不入栈),则将栈元素弹出并输出,直到遇到左括号为止(注意左括号只弹出不打印);
5.遍历结束后,判空,若栈不为空,弹出并输出所有栈中元素。
注意:
当然,也可把左括号和右括号都并入操作符中,如此,左括号为优先级最高的元素,而右括号优先级最低。我的代码中,括号单独拉出来处理。
代码如下:
//主函数
int main()
{
int i;
char ch[100];
char c;
scanf("%s",ch);
link *l=init();
for(i=0;ch[i]!='\0';i++){
//如果输入的是字母,直接输出
if(ch[i]<='z'&&ch[i]>='a'){
printf("%c",ch[i]);
continue;//跳出本次循环
}
//如果输入的是操作符
switch(ch[i]){
case '+':
//先判空,若为空,直接入栈
if(isEmply(l)) {ruzhan(l,'+'); break;}
//若非空,取栈顶
c =getTop(l);
//若遇到“(”,入栈
if(c=='('){ruzhan(l,'+'); break;}
//若栈顶元素比输入元素优先级高或相等,弹出并打印栈顶元素
while((c=='+' || c=='-')||(c=='*' || c=='/'))//此处皆为||,有无括号关系不大
{
chuzhan(l);
printf("%c",c);
c=getTop(l);//自带判空操作,若为空,则c为 '\0',自动退出循环
}
ruzhan(l,'+');//将扫描到的操作符压入栈中
break;
//‘-’与‘+’同理
case '-':
if(isEmply(l)) {ruzhan(l,'-'); break;}
c =getTop(l);
if(c=='('){ruzhan(l,'-'); break;}
while((c=='+' || c=='-')||(c=='*' || c=='/')){
chuzhan(l);
printf("%c",c);
c=getTop(l);
}
ruzhan(l,'-');
break;
case '*':
if(isEmply(l)) {ruzhan(l,'*'); break;}
c=getTop(l);
//为什么不判断栈顶元素是否为左括号????????????
if(c=='+'||c=='-'){ ruzhan(l,'*'); break;} //如果栈顶元素优先级比操作符低 ,直接将操作符压入栈
while(c=='*'||c=='/'){
chuzhan(l);//为什么只弹出,不输出
c=getTop(l);
}
ruzhan(l,'*');
break;
//与‘*’同理
case '/':
if(isEmply(l)) {ruzhan(l,'/'); break;}
c=getTop(l);
if(c=='+'||c=='-'){ ruzhan(l,'/'); break;}
while(c=='*'||c=='/'){
chuzhan(l);
c=getTop(l);
}
ruzhan(l,'/');
break;
case '(':
ruzhan(l,'(');
break;
case ')':
c= getTop(l);
while(c!='('){
printf("%c",c);// printf与chuzhan可交换
chuzhan(l);
c = getTop(l);
}
chuzhan(l);//如果c=='(',将左括号弹出
break;
}
}
while(!isEmply(l))//如果已遍历完,栈中还有剩余元素,皆按顺序弹出打印
{
c=getTop(l);
printf("%c",c);//printf与chuzhan可交换
chuzhan(l);
}
return 0;
}
运行截图: