描述
人们熟悉的四则运算表达式称为中缀表达式,例如(23+34*45/(5+6+7))。在程序设计语言中,可以利用堆栈的方法把中缀表达式转换成保值的后缀表达式(又称逆波兰表示法),并最终变为计算机可以直接执行的指令,得到表达式的值。
给定一个中缀表达式,编写程序,利用堆栈的方法,计算表达式的值。
输入
第一行为测试数据的组数N
接下来的N行,每行是一个中缀表达式。表达式中只含数字、四则运算符和圆括号,操作数都是正整数,数和运算符、括号之间没有空格。中缀表达式的字符串长度不超过600。
输出
对每一组测试数据输出一行,为表达式的值
解法
该问题可以转换为两个子问题:
1、将中缀表达式转换为后缀表达式
2、利用栈对后缀表达式求值
中缀表达式转后缀表达式
算法: 可以使用栈来完成中缀表达式到后缀表达式的转换
1、栈stack[]用来存储操作符,top指向栈顶,但不存储元素,top=0表示栈为空
2、从左向右遍历中缀表达式
a.如果遇到的是操作数num,则直接输出到后缀表达式
b.如果遇到的是操作符op,则有几种情况:
b.1.如果op==')',则依次弹出栈顶直到弹出'(',但'('不输出到后缀表达式
b.2:如果op=='(',则直接入栈
b.3:如果栈为空,则直接入栈
b.4:如果op的优先级高于栈顶操作符的优先级,则入栈
b.5:如果op的优先级低于或等于栈顶操作符的优先级,则依次弹出栈顶直到op的优先级高于栈顶操作符的优先级(或栈为空),再将op入栈
3、遍历完时,如果栈仍不为空,则依次弹出栈顶直到栈为空
具体的代码如下:
1 int mycmp(char a, char b) { 2 if(b == '(') 3 return 1;//左括号直接入栈 4 else if((b == '*' || b == '/') &&(a == '+' || a == '-' || a == '(')) 5 return 1;//*、/优先级高于+、-、(,入栈 6 else if((b == '+' || b == '-') && (a == '(')) 7 return 1;//+、-优先级高于(,入栈 8 else 9 return 0; 10 } 11 12 /*中缀表达式转后缀表达式 13 中缀表达式之间无分割 14 后缀表达式操作数、操作符之间用空格分割,便于区分不同操作数*/ 15 void infix_to_suffix(char* infix, char* suffix) { 16 int i, k, j=0, top=0; 17 char stack[1000];//存储运算符的栈 18 19 for(i=0; infix[i]!='