筆試題 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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章