计算表达式

粗糙的实现,能够完成“12*3+4*11/(2-5)*2”之类的整形运算。方法是通过两个栈,一个记录操作数,一个记录操作符,然后用map记录优先级。/和*的优先级要一样,否则会有4*11/2是22还是20这样的错误。括号的处理是"("入栈,")"开始回退到"("。因为除号的两个操作数有顺序,弹出栈的时候要注意。

#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <map>
using namespace std;

// case:
// 1+2*3+5-6/7 = 12
// 12*3+4*11/2-5*2 = 48
// 1+2*((3+(5-6)/1)+6)*3 = 49
// 12*3+4*11/(2-5)*2 = 8

map<char, int> pmap; // priority_map
void init()
{
	pmap.insert(make_pair('#', 0));
	pmap.insert(make_pair('+', 1));
	pmap.insert(make_pair('-', 1));
	pmap.insert(make_pair('*', 2));
	pmap.insert(make_pair('/', 2));
}

int get_pri(char c)
{
	if (pmap.count(c) != 0)
	{
		return pmap[c];
	}
	return -1;
}

int eval(char op, int num1, int num2)
{
	if (op == '+') return num1 + num2;
	if (op == '-') return num1 - num2;
	if (op == '*') return num1 * num2;
	if (op == '/') return num1 / num2;
}

void operate(stack<char> &op_stack,
	stack<int> &num_stack)
{
	int num2 = num_stack.top();
	num_stack.pop();
	int num1 = num_stack.top();
	num_stack.pop();
	char op = op_stack.top();
	op_stack.pop();
	int res = eval(op, num1, num2);
	num_stack.push(res);
}

int calc(string s)
{
	s = s + '#';
	stack<char> op_stack;
	stack<int> num_stack;
	for (int i = 0; i < s.length(); i++)
	{
		if (isdigit(s[i]))
		{
			int num = 0;
			int j = i;
			while (isdigit(s[j]) && j < s.length())
			{
				num = num * 10 + (s[j] - '0');
				j++;
			}
			num_stack.push(num);
			i = j - 1;
		}
		else if (s[i] == '(')
		{
			op_stack.push(s[i]);
		}
		else if (s[i] == ')')
		{
			while (op_stack.top() != '(')
			{
				operate(op_stack, num_stack);
			}
			op_stack.pop();
		}
		else //  '*', '/', '+', '-', '#'
		{
			while (!op_stack.empty() && get_pri(op_stack.top()) >= get_pri((s[i])))
			{
				operate(op_stack, num_stack);
			}
			op_stack.push(s[i]);
		}
	}
	return num_stack.top();
}

int main() {
	init();
    int c = calc("12*3+4*11/(2-5)*2");
	cout << c << endl;
}

  

转载于:https://www.cnblogs.com/lautsie/p/3427441.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值