[数据结构]--中缀表达式求值

51 篇文章 2 订阅
29 篇文章 8 订阅

算术表达式求值

算术四则运算遵循以下三条原则

  1. 先乘除,后加减。
  2. 从左到右。
  3. 先括号内,后括号外。

在运算的每一步,任意两个相继出现的算符op1和算法op2之间存在优先级关系,以下三种关系:op1 < op2 ,op1 > op2,op1 = op2。

算法步骤:

  1. 初始化操作数栈OPND, 操作符栈OPTR,表达式起始符’#'入OPTR。
  2. 扫描表达式,读一个字符,直至扫描完毕到’#‘结束字符或者OPTR栈顶元素不为’#'时,循环执行以下操作:
    • 若ch不是运算符,压入OPND,读下一个字符ch。
    • 若ch是运算符,根据ch与OPTR栈顶元素的运算符优先级结果:
      • 小于,ch压入OPTR栈,读一个字符ch。
      • 大于,弹出OPTR栈顶运算符,从OPND弹出两个数,进行运算结果压入OPND。
      • 等于,OPTR的栈顶元素是’(‘且ch是’)’,弹出括号表示括号匹配成功,读入下一个字符ch。
  3. OPND栈顶元素为表达式求值的结果。
#include <iostream>
#include <stack>
#include <cstdio>
using namespace std;

// 判断ch是否为运算符
bool isOperator(char ch) {
	if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#') {
		return true;
	} else {
		return false;
	}
}

/**
 * 比较运算符a和b的优先级
 @prama a char 运算符a
 @prama b char 运算符b
 @return int 
 1为运算符优先级 a > b
 0为运算符优先级 a = b
 -1为运算符优先级 a < b
 */
int compareOperator(char a, char b) {
	if (a == '+') {
		if (b == '+' || b == '-' || b == ')' || b == '#') {
			return 1;
		} else {
			return -1;
		}
	}
	if (a == '-') {
		if (b == '+' || b == '-' || b == ')' || b == '#') {
			return 1;
		} else {
			return -1;
		}
	}
	if (a == '*') {
		if (b == '(') {
			return -1;
		} else {
			return 1;
		}
	}
	if (a == '/') {
		if (b == '(') {
			return -1;
		} else {
			return 1;
		}
	}
	if (a == '(') {
		if (b == ')') {
			return 0;
		} else {
			return -1;
		}
	}
	if (a == ')') {
		return 1;
	}
	if (a == '#') {
		if (b == '#') {
			return 0;
		} else {
			return -1;
		}
	}
	cout << "error" << endl;
	return -1;
}

// 计算a op b
int calculate(int a, int b, char op) {
	if (op == '+') {
		return a + b;
	} else if (op == '-') {
		return a - b;
	} else if (op == '*') {
		return a * b;
	} else if (op == '/') {
		return a / b;
	}
	cout << "error" << endl;
	return -1;
}

int main() {
	stack<int> OPND;// 初始化操作数栈
	stack<char> OPTR; // 初始化运算符栈

	OPTR.push('#'); // 表达式起始符#压入栈中
	char ch;
	cin >> ch;
	while (ch != '#' || OPTR.top() != '#') {
		if (!isOperator(ch)) {
			// 操作数
			OPND.push(ch - '0');
			cin >> ch;
		} else {
			// 运算符
			int res = compareOperator(OPTR.top(), ch);
			if (res == -1) {
				// 运算符栈 栈顶元素优先级小于ch
				OPTR.push(ch);
				cin >> ch;
			} else if (res == 1) {
				// 栈顶元素优先级高于ch
				int opnd1, opnd2; // 操作数1和操作数2
				char optr; // 运算符

				opnd2 = OPND.top();
				OPND.pop();
				opnd1 = OPND.top();
				OPND.pop();
				optr = OPTR.top();
				OPTR.pop();

				// 计算
				int tmp = calculate(opnd1, opnd2, optr);
				OPND.push(tmp);
			} else if (res == 0) {
				// ()去括号
				OPTR.pop();	
				cin >> ch;
			}
		}
	}
	cout << OPND.top() << endl;
	return 0;
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值