栈的经典应用, 表达式求值和逆波兰表达式求取, 思路相同.
题目比较简单, 但是具体而言细节是很多的, 题目可以取巧, 因为只涉及到±*/两种优先级, 所以可以直接处理. 不必使用表达式求值的思路, 但是这个思路更加泛用.
具体而言细节还是很多的, 比如哨兵的加入. 另外就是拓展的话优先级矩阵需要改进. 编程其实就是分解, 编写的过程. 像这道题, 思路其实很简单.
#include
#include
#include
#include
#include
//#include"common.h"
using namespace std;
const int MAXN = 205;
char str[MAXN];
int mat[][5] = {
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,0,0,
1,1,1,0,0,
};
stack nums;
stack ops;
//操作符 -> 下标
int getIdx(char c) {
switch (c) {
case '\0':return 0;
case '+':return 1;
case '-':return 2;
case '*':return 3;
case '/':return 4;
default : return -1;
}
}
//执行操作
double opt(double a, double b, char c) {
switch (c) {
case '+':return a + b;
case '-':return a - b;
case '*':return a*b;
case '/':return a / b;
default : return -1;
}
}
int readNum(int &i){
int r = str[i]-'0';
while(isdigit(str[i+1])){
r=r*10+str[++i]-'0';
}
return r;
}
int main() {
char c, tc;
double r, a, b;
while (gets(str)) {
if (str[0] == '0'&&str[1] == 0)break;
//初始化
while (!nums.empty()) nums.pop();//清空栈
while (!ops.empty()) ops.pop();
ops.push('\0');//前后的哨兵
int i = 0;
//遍历分析字符串
do {
c = str[i];
tc = ops.top();
if(c==' ')continue;//空格跳过
//当前c数字进栈
if (isdigit(c)) {
nums.push(readNum(i));
continue;
}
//当前c为操作符, 则判断是否计算
if (mat[getIdx(c)][getIdx(tc)]) {//c优先级大于tc,进栈
ops.push(c);
}
else {//c优先级小于tc,计算
b = nums.top(); nums.pop();//取二操作数
a = nums.top(); nums.pop();
ops.pop();
r = opt(a, b, tc);//执行计算
nums.push(r);
--i;//修正i
}
} while (str[i++] != 0);
printf("%.2f\n", nums.top());
}
return 0;
}
*/