使用栈来计算算术表达式

之所以写这个,是因为最近在学习C++的过程中,C++primer 第五版 9.6的习题跟这个有关,在网上看看些人的思路,也就做出来了,正好写到博客里面。

原题如下:

使用 stack 处理括号化的表达式。当你看到一个左括号,将其记录下来。当你在一个左括号之后看到一个右括号,从 stack 中 pop 对象,直至遇到左括号,

将左括号也一起弹出栈。然后将一个值(括号内的运算结果)push 到栈中,表示一个括号化的(子)表达式已经处理完毕,被其运算结果所替代。

题目也给了思路,具体上代码:

#include "stdafx.h"
#include<iostream>
#include<queue>
#include<vector>
#include<string>
#include<stack>
using namespace std;
vector<string>prase(char *str)  //分离每个符号
{
	vector<string>tokens;
	int len = strlen(str);
	char *p = (char*)malloc((len + 1) * sizeof(char));
	int i = 0, j = 0;
	while (i < len) //去除空格
	{
		if (str[i] == ' ')
		{
			i++;
			continue;
		}
		p[j++] = str[i++];
	}

	p[j] = '\0';
	j = 0;
	len = strlen(p);
	while (j < len)
	{
		char temp[2] = { 0 }; //存储符号
		string token;
		switch (p[j])
		{
		case '+':
		case '*':
		case '/':
		case '(':
		case ')':
			temp[0] = p[j];
			temp[1] = '\0';
			token = temp;
			tokens.push_back(token);
			break;
		case '-':
			if (p[j - 1] == ')' || isdigit(p[j - 1])) //不能使用--j,会死循环
			{
				temp[0] = p[j];
				temp[1] = '\0';
				token = temp;
				tokens.push_back(token);
				break;
			}
			else
			{
				temp[0] = '$';
				temp[1] = '\0';
				token = temp;
				tokens.push_back(token);
				break;
			}
		default:
			i = j;
			while (isdigit(p[i]))
				i++;

			char *operand = (char*)malloc((i - j + 1) * sizeof(char));
			memset(operand, 0, i - j + 1);
			memcpy(operand, p + j, i - j);
			operand[i - j] = '\0';
			token = operand;
			tokens.push_back(token);
			free(operand);

			j = i - 1;
			break;
		}
		j++;

	}
	free(p);
	return tokens;
}
int priority(string opd)
{
	int level;
	if (opd == "$")
		level = 3;
	else if (opd == "*" || opd == "/")
		level = 2;
	else if (opd == "+" || opd == "-")
		level = 1;
	else if (opd == "(" || opd == ")")
		level = 0;
	return level;
}
void calculate(stack<int>& opdStack, string opt)
{
	if (opt == "+")
	{
		int rOpd = opdStack.top();
		opdStack.pop();
		int lOpd = opdStack.top();
		opdStack.pop();
		int result = rOpd + lOpd;
		opdStack.push(result);
	}
	else if (opt == "-")
	{
		int rOpd = opdStack.top();
		opdStack.pop();
		int lOpd = opdStack.top();
		opdStack.pop();
		int result = lOpd - rOpd;
		opdStack.push(result);
	}
	else if (opt == "*")
	{
		int rOpd = opdStack.top();
		opdStack.pop();
		int lOpd = opdStack.top();
		opdStack.pop();
		int result = lOpd * rOpd;
		opdStack.push(result);
	}
	else if (opt == "/")
	{
		int rOpd = opdStack.top();
		opdStack.pop();
		int lOpd = opdStack.top();
		opdStack.pop();
		int result = lOpd / rOpd;
		opdStack.push(result);
	}
	else if (opt == "$")
	{
		int result = opdStack.top();
		opdStack.pop();
		result = -result;
		opdStack.push(result);
	}
}
int computationalExp(char *str)
{
	vector<string>tokens = prase(str);
	stack<int>opdStack;
	stack<string>optStack;

	for (int i = 0; i < tokens.size(); i++)
	{
		string token = tokens[i];
		if (token == "+" || token == "-" || token == "*" || token == "/" || token == "$")
		{
			if (optStack.empty())
			{
				optStack.push(token);
			}
			else
			{
				int tokenPriority = priority(token);
				string topOptStack = optStack.top();
				int optPriority = priority(topOptStack);
				if (tokenPriority > optPriority) //运算操作符优先于栈顶操作符,则入栈
				{
					optStack.push(token);
				}
				else
				{//否则弹出操作符和操作数进行计算,直至当前操作符优先栈顶操作符时,入栈
					while (tokenPriority <= optPriority)
					{
						calculate(opdStack, topOptStack);
						optStack.pop();
						if (optStack.size() > 0)
						{
							topOptStack = optStack.top();
							optPriority = priority(topOptStack);
						}
						else
						{
							break;
						}
					}
					optStack.push(token);
				}
			}
		}
		else if (token == "(")
		{
			optStack.push(token);
		}
		else if (token == ")")
		{
			while (optStack.top() != "(")
			{
				string topOpt = optStack.top();
				calculate(opdStack, topOpt);
				optStack.pop();
			}
			optStack.pop();//弹出"("
		}
		else
		{
			opdStack.push(stoi(token));//操作数入栈
		}
	}
	while (optStack.size() != 0)
	{
		string topOpt = optStack.top();
		calculate(opdStack, topOpt);
		optStack.pop();
	}
	return opdStack.top();
}
int main()
{
	char *str = "3+5-6*-9/3+(4+3*7)";
	cout << computationalExp(str) << endl;
	return 0;
}
如有啥问题,请多多指教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值