c3, 题目:简单的计算器【栈应用,表达式求值】

栈的经典应用, 表达式求值和逆波兰表达式求取, 思路相同.
题目比较简单, 但是具体而言细节是很多的, 题目可以取巧, 因为只涉及到±*/两种优先级, 所以可以直接处理. 不必使用表达式求值的思路, 但是这个思路更加泛用.
具体而言细节还是很多的, 比如哨兵的加入. 另外就是拓展的话优先级矩阵需要改进. 编程其实就是分解, 编写的过程. 像这道题, 思路其实很简单.

  1. 栈表达式求值的思路, 可以参考任意数据结构参考书
  2. 不断对比当前操作符和栈顶操作符, 计算或进栈
#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;
}

*/

你可能感兴趣的:(算法编程)