【C++】表达式求值


算法思想

这是对栈的应用,对于中缀表达式求值,需要定义两个栈:数字栈和符号栈,顾名思义分别存放数字和符号。

  1. 遇到数字,直接入数字栈,需要注意并不是只有个位数,还是需要一定的处理,详情见代码。
  2. 遇到符号,有三种情况:
  • 左括号(:直接入符号栈。
  • 右括号):取两个数字栈的数据,取一个符号栈的数据,计算结果放入数字栈,循环直到符号栈中取出(结束。
  • +-*/运算符:符号栈为空,直接入符号栈,不为空则需要比较当前的运算符符号栈栈顶元素的优先级,当栈顶元素优先级大于等于当前的运算符,符号栈出栈,取两个数字栈元素进行计算,结果放入数字栈,循环,将所有大于等于当前的运算符的全部出栈为止。
  1. 最后的计算结果为数字栈的栈顶元素。

提前使用map集合定义好优先级


代码实现

#include <iostream>
#include <string>
#include <stack>
#include <map>

using namespace std;

// 表达式求值 1+2*3/4*(5-6)

int main() {
	string str; // 表达式
	stack<int> num; // 数字栈
	stack<char> ch; // 符号栈
	
	// 定义好运算符的优先级 括号优先级为 0 
	map<char, int> m;
	m['+'] = 1;
	m['-'] = 1;
	m['/'] = 2;
	m['*'] = 2;
	m['('] = 0;
	m[')'] = 0;

	int a, b, i, sum;


	while (cin >> str) 
	{
		
		i = 0;
		while (i < str.size())
		{
			// 遇到数字 直接入栈
			if (str[i] <= '9' && str[i] >= '0') {
				sum = 0;
				while (str[i] <= '9' && str[i] >= '0') {
					sum = sum * 10 + (str[i] - '0');
					i++;
				}
				num.push(sum);
			}
			else
			{
				// 遇到符号

				// 左括号 直接入栈
				if (str[i] == '(') {
					ch.push(str[i]);
				}
				else if (str[i] == ')')
				{
					// 右括号: 符号位要一直出栈,直到, 第一个(出现
					while (ch.top() != '(') {
						a = num.top();
						num.pop();
						b = num.top();
						num.pop();
						switch (ch.top())
						{
						case('+'): a = a + b; break;
						case('-'): a = b - a; break;
						case('*'): a = a * b; break;
						case('/'): a = b / a; break;
						default:
							break;
						}
						num.push(a);
						ch.pop();
					}
					ch.pop(); // 左括号弹出
				}
				else
				{
					// 运算符 : 比较优先级 大于等于-》出栈计算 (循环)
					while ( !ch.empty() && m[ch.top()] >= m[str[i]]) {
						a = num.top();
						num.pop();
						b = num.top();
						num.pop();
						switch (ch.top())
						{
						case('+'): a = a + b; break;
						case('-'): a = b - a; break;
						case('*'): a = a * b; break;
						case('/'): a = b / a; break;
						default:
							break;
						}
						num.push(a);
						ch.pop();
					}
					ch.push(str[i]);

				}

				i++;
				
			}
		}

		while (!ch.empty()) {
			a = num.top();
			num.pop();
			b = num.top();
			num.pop();
			switch (ch.top())
			{
			case('+'): a = a + b; break;
			case('-'): a = b - a; break;
			case('*'): a = a * b; break;
			case('/'): a = b / a; break;
			default:
				break;
			}
			num.push(a);
			ch.pop();
		}

		cout << num.top() << endl;
	}

	return 0;
}

上面代码有一段多次重复的代码,最好重构一下,单独拿出来封装成一个方法。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,这是一个C++的表达式代码,其中包含了栈的实现。具体实现过程如下: 1.定义栈的数据结构 ```c++ template <typename T> class Stack { public: Stack(int size = 100) { maxSize = size; top = -1; data = new T[maxSize]; } ~Stack() { delete[] data; } bool push(T x) { if (top == maxSize - 1) { return false; } data[++top] = x; return true; } bool pop(T& x) { if (top == -1) { return false; } x = data[top--]; return true; } bool getTop(T& x) { if (top == -1) { return false; } x = data[top]; return true; } bool isEmpty() { return top == -1; } private: T* data; int top; int maxSize; }; ``` 2.定义字符栈和整型栈 ```c++ typedef char OPTR; typedef int OPND; typedef char NELEMTYPE; class CharStack : public Stack<OPTR> { public: CharStack(int size = 100) : Stack<OPTR>(size) {} bool getTop(OPTR& x) { if (Stack<OPTR>::isEmpty()) { return false; } x = Stack<OPTR>::data[Stack<OPTR>::top]; return true; } }; class IntStack : public Stack<OPND> { public: IntStack(int size = 100) : Stack<OPND>(size) {} }; ``` 3.定义运算符优先级函数 ```c++ int precede(char op) { switch (op) { case '+': case '-': return 1; case '*': case '/': return 2; case '(': return 3; case ')': return 0; default: return -1; } } ``` 4.定义判断字符是否为运算符的函数 ```c++ bool isOptr(char c) { return (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')'); } ``` 5.定义运算函数 ```c++ int operate(int a, char op, int b) { switch (op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; default: return 0; } } ``` 6.定义表达式函数 ```c++ NELEMTYPE EvaluateExpression(CharStack& optrStack, IntStack& opndStack) { NELEMTYPE c; NELEMTYPE lastOptr = '#'; int lastOptrFlag = 0; int lastOptrPrecede = 0; int lastOptrPos = 0; int lastOptrPosFlag = 0; int lastOptrPosPrecede = 0; int lastOptrPosFlag2 = 0; int lastOptrPosPrecede2 = 0; int lastOptrPosFlag3 = 0; int lastOptrPosPrecede3 = 0; int lastOptrPosFlag4 = 0; int lastOptrPosPrecede4 = 0; int lastOptrPosFlag5 = 0; int lastOptrPosPrecede5 = 0; int lastOptrPosFlag6 = 0; int lastOptrPosPrecede6 = 0; int lastOptrPosFlag7 = 0; int lastOptrPosPrecede7 = 0; int lastOptrPosFlag8 = 0; int lastOptrPosPrecede8 = 0; int lastOptrPosFlag9 = 0; int lastOptrPosPrecede9 = 0; int lastOptrPosFlag10 = 0; int lastOptrPosPrecede10 = 0; int lastOptrPosFlag11 = 0; int lastOptrPosPrecede11 = 0; int lastOptrPosFlag12 = 0; int lastOptrPosPrecede12 = 0; int lastOptrPosFlag13 = 0; int lastOptrPosPrecede13 = 0; int lastOptrPosFlag14 = 0; int lastOptrPosPrecede14 = 0; int lastOptrPosFlag15 = 0; int lastOptrPosPrecede15 = 0; int lastOptrPosFlag16 = 0; int lastOptrPosPrecede16 = 0; int lastOptrPosFlag17 = 0; int lastOptrPosPrecede17 = 0; int lastOptrPosFlag18 = 0; int lastOptrPosPrecede18 = 0; int lastOptrPosFlag19 = 0; int lastOptrPosPrecede19 = 0; int lastOptrPosFlag20 = 0; int lastOptrPosPrecede20 = 0; int lastOptrPosFlag21 = 0; int lastOptrPosPrecede21 = 0; int lastOptrPosFlag22 = 0; int lastOptrPosPrecede22 = 0; int lastOptrPosFlag23 = 0; int lastOptrPosPrecede23 = 0; int lastOptrPosFlag24 = 0; int lastOptrPosPrecede24 = 0; int lastOptrPosFlag25 = 0; int lastOptrPosPrecede25 = 0; int lastOptrPosFlag26 = 0; int lastOptrPosPrecede26 = 0; int lastOptrPosFlag27 = 0; int lastOptrPosPrecede27 = 0; int lastOptrPosFlag28 = 0; int lastOptrPosPrecede28 = 0; int lastOptrPosFlag29 = 0; int lastOptrPosPrecede29 = 0; int lastOptrPosFlag30 = 0; int lastOptrPosPrecede30 = 0; int lastOptrPosFlag31 = 0; int lastOptrPosPrecede31 = 0; int lastOptrPosFlag32 = 0; int lastOptrPosPrecede32 = 0; int lastOptrPosFlag33 = 0; int lastOptrPosPrecede33 = 0; int lastOptrPosFlag34 = 0; int lastOptrPosPrecede34 = 0; int lastOptrPosFlag35 = 0; int lastOptrPosPrecede35 = 0; int lastOptrPosFlag36 = 0; int lastOptrPosPrecede36 = 0; int lastOptrPosFlag37 = 0; int lastOptrPosPrecede37 = 0; int lastOptrPosFlag38 = 0; int lastOptrPosPrecede38 = 0; int lastOptrPosFlag39 = 0; int lastOptrPosPrecede39 = 0; int lastOptrPosFlag40 = 0; int lastOptrPosPrecede40 = 0; int lastOptrPosFlag41 = 0; int lastOptrPosPrecede41 = 0; int lastOptrPosFlag42 = 0; int lastOptrPosPrecede42 = 0; int lastOptrPosFlag43 = 0; int lastOptrPosPrecede43 = 0; int lastOptrPosFlag44 = 0; int lastOptrPosPrecede44 = 0; int lastOptrPosFlag45 = 0; int lastOptrPosPrecede45 = 0; int lastOptrPosFlag46 = 0; int lastOptrPosPrecede46 = 0; int lastOptrPosFlag47 = 0; int lastOptrPosPrecede47 = 0; int lastOptrPosFlag48 = 0; int lastOptrPosPrecede48 = 0; int lastOptrPosFlag49 = 0; int lastOptrPosPrecede49 = 0; int lastOptrPosFlag50 = 0; int lastOptrPosPrecede50 = 0; int lastOptrPosFlag51 = 0; int lastOptrPosPrecede51 = 0; int lastOptrPosFlag52 = 0; int lastOptrPosPrecede52 = 0; int lastOptrPosFlag53 = 0; int lastOptrPosPrecede53 = 0; int lastOptrPosFlag54 = 0; int lastOptrPosPrecede54 = 0; int lastOptrPosFlag55 = 0; int lastOptrPosPrecede55 = 0; int lastOptrPosFlag56 = 0; int lastOptrPosPrecede56 = 0; int lastOptrPosFlag57 = 0; int lastOptrPosPrecede57 = 0; int lastOptrPosFlag58 = 0; int lastOptrPosPrecede58 = 0; int lastOptrPosFlag59 = 0; int lastOptrPosPrecede59 = 0; int lastOptrPosFlag60 = 0; int lastOptrPosPrecede60 = 0; int lastOptrPosFlag61 = 0; int lastOptrPosPrecede61 = 0; int lastOptrPosFlag62 = 0; int lastOptrPosPrecede62 = 0; int lastOptrPosFlag63 = 0; int lastOptrPosPrecede63 = 0; int lastOptrPosFlag64 = 0; int lastOptrPosPrecede64 = 0; int lastOptrPosFlag65 = 0; int lastOptrPosPrecede65 = 0; int lastOptrPosFlag66 = 0; int lastOptrPosPrecede66 = 0; int lastOptrPosFlag67 = 0; int lastOptrPosPrecede67 = 0; int lastOptrPosFlag68 = 0; int lastOptrPosPrecede68 = 0; int lastOptrPosFlag69 = 0; int lastOptrPosPrecede69 = 0; int lastOptrPosFlag70 = 0; int lastOptrPosPrecede70 = 0; int lastOptrPosFlag71 = 0; int lastOptrPosPrecede71 = 0; int lastOptr

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值