笔试题 C++ 利用栈实现带括号的加减乘除

参考其他网友的思路,改了原来的bug。对浮点数、整数都适用。
维护三个栈,分别存括号、 + -*/ 、数字
首先遍历匹配括号,取出括号内的子字符串;
然后计算只包括 + -*/ 及数字的子字符串的结果,先计算* / ,将 + -全部入栈,然后计算只包含 + -的结果。

#include<iostream>
#include<string>
#include<sstream>
#include<stack>
#include<algorithm>
using namespace std;

double calc(string s)
{
	char c;//符号
	double a, b, val;//左操作数、右操作数、计算结果
	stack<double> num;//存数字
	stack<char> op;//存操作符

	//以+或-开头,在开头补零
	if (s[0] == '+' || s[0] == '-')
	{
		s = "0" + s;
	}
	//将第一个数字压入数字栈
	stringstream ss(s);
	ss >> val;
	num.push(val);
	//每次读取一个符号和数字
	while (ss >> c >> val)
	{
		//如果符号是*/,直接与前面的数计算,消去*/
		if (c == '*' || c == '/')
		{
			if (c == '*')
			{
				val *= num.top();
			}
			else
			{
				val = num.top() / val;
			}
			num.pop();//弹出已经计算过的数
			num.push(val);//压入计算后的结果
		}
		else//符号是+-
		{
			//将取到的数和符号压栈,op栈中只留+-
			num.push(val);
			op.push(c);
		}
	}
	//操作符栈不为空,只有加减运算
	while(!op.empty())
	{
		a = num.top();
		num.pop();
		b = num.top();
		num.pop();
		if (op.top() == '+')
		{
			num.push(b + a);
		}
		else
		{
			num.push(b - a);
		}
		op.pop();
	}
	return num.top();
}

int main()
{
	string str;//表达式字符串
	getline(cin, str);
	stack<int> kuohao;//存括号
	int len = str.size();
	int from, to;
	for (int i = 0; i < len; i++)
	{
		if (str[i] == '(' || str[i] == ')')
		{
			//括号不匹配
			if (kuohao.empty() || str[i] == str[kuohao.top()])
			{
				kuohao.push(i);//栈里存放的是'('')'在str中的index
			}
			else//括号匹配
			{
				from = kuohao.top();
				to = i; //定位到一组()
				kuohao.pop();//计算过的出栈
				//求解括号中的表达式
				double tmp = calc(str.substr(from + 1, to - from - 1));
				//把所求结果替换掉括号部分的表达式
				stringstream ss;
				ss << tmp;
				string tmpS;
				ss >> tmpS; //double->string
				str.replace(str.begin() + from, str.begin() + to + 1, tmpS.begin(), tmpS.end());//'('...')'之间有to-from+1个字符!
				len = str.size();//循环条件记得更新
				i = from - 1;
			}
		}
	}
	double result = calc(str);
	cout << result << endl;
	return 0;
}
发布了21 篇原创文章 · 获赞 15 · 访问量 4986

猜你喜欢

转载自blog.csdn.net/zdluffy/article/details/98887407
今日推荐