含括号的四则运算

总体思路:需要用到栈,从中缀表达式到后缀表达式,再把后缀表达式转化为结果,比如计算9+(3-1)*5+4/2,这个式子就叫做中缀表达式,然后我们需要把它转化成后缀表答式,方法将中缀表达式从左到右读取,如果是数字,直接输出到后缀表达式,如果是字符,则如果是右括号,把从栈顶开始到栈中左括号的字符输出到后缀表达式,如果是运算符,优先级不比栈顶元素(只能是字符,遇到括号停止)高的,输出到后缀表达式,当读取完后,栈还有剩余,全部从栈顶输出到后缀表达式,这样,后缀表达式就是931-5*+42/+;

然后把后缀表达式转化为结果,方法:从左到右读取后缀表达式,如果是数字,则进栈,如果是运算符#,把栈顶的第一个字符取出来当作a,再把栈顶的第二个取出来当作b,进行b#a的运算,再把结果放进栈,知道读取完毕后,栈中的数字就是答案。

所以,在中缀表达式转换到后缀表达式中,我们可以用a栈存后缀表达式中的数字,b栈存还没处理完毕的运算符,当有运算符要输出到后缀表达式了,马上用a栈的前两个字母进行运算即可。下面的代码支持输入小数。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
stack<char> a;//存运算符
stack<double> b;//存数字
void calulate(char to)//运算符输出到后缀表达式时,进行运算
{
	double x = b.top();
	b.pop();
	double y = b.top();
	b.pop();
	switch (to)
	{
	case '+':b.push(y + x); break;
	case '-':b.push(y - x); break;
	case '*':b.push(y*x); break;
	case '/':b.push(y / x); break;
	}
}
int main()
{
	char s[1000];
	while (cin >> s)
	{
		while (!a.empty())
			a.pop();
		while (!b.empty())
			b.pop();
		int len = strlen(s);
		int ans = 0;
		for (int i = 0; i < len; i++)//逐个读取中缀表达式
		{
			if (s[i] == '.')//处理小数点
			{
				double d = b.top();
				b.pop();
				i++;
				int ant = 1;
				while (s[i] >= '0'&&s[i] <= '9')
				{
					double dd = s[i] - '0';
					for (int j = 0; j < ant; j++)
						dd = dd / 10.0;
					ant++;
					d += dd;
					i++;
				}
				b.push(d);
				i--;
			}
			else if (s[i] >= '0'&&s[i] <= '9')
			{
				double d = s[i] - '0';
				i++;
				while (s[i] >= '0'&&s[i] <= '9')//处理十位以上的数字
				{
					d = d*10.0 + s[i] - '0';
					i++;
				}
				i--;
				b.push(d);
			}
			else
			{
				if (s[i] == '(')//左括号必须加入栈
					a.push(s[i]);
				else
				{
					if (a.empty())//空栈即把其加入
					{
						a.push(s[i]);
					}
					else
					{
						if (s[i] == ')')//右括号时,把直到左括号的符号输出,即进行运算
						{
							while (a.top() != '(')
							{
								calulate(a.top());
								a.pop();
							}
							a.pop();
						}
						else
						{
							if (s[i] == '+' || s[i] == '-')//+或-不比任何运算符高,即进行运算,知道遇到括号或栈空
							{
								while (!a.empty())
								{
									if (a.top() == '(' || a.top() == ')')
										break;
									else
									{
										calulate(a.top());
										a.pop();
									}
								}
							}
							else
							{
								while (!a.empty())//*和/只处理+和-,同上
								{
									if (a.top() == '(' || a.top() == ')')
										break;
									if (a.top() == '*' || a.top() == '/')
									{
										calulate(a.top());
										a.pop();
									}
									else
									{
										break;
									}
								}
							}
							a.push(s[i]);
						}
					}
				}
			}
		}
		while (!a.empty())//栈中剩余的运算符,也要进行运算
		{
			calulate(a.top());
			a.pop();
		}
		cout << "="<< b.top() << endl;
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值