【数据结构】第三届中国计量大学ACM程序设计竞赛个人赛 问题A: Arithmetic Problems(只含加减乘除的中缀表达式计算)

传送门
题目大意:给出一个不含括号的且只含加减乘除运算符和数字的字符串作为待计算的中缀表达式。运算符的计算规则依据下方图片中描述的形式给出。目的:求中缀表达式的值。
在这里插入图片描述
解题思路:定义两个栈,一个操作符栈,一个运算数栈。首先遍历表达式,遇到操作数直接入栈,遇到运算符将优先级高的 “乘除”(实际意义中的乘除,接下来的加减也是实际意义中的加减)做相应的运算并在操作数栈中存入运算后的结果;将优先级低的 “加减” 堆进运算符栈。
经过上述的一遍操作,最后会留下一个只含加减运算以及相应的运算数在表达式中。

例如: 将 1 ∗ 2 + 4 ∗ 6 − 8 / 4 − 2 经 过 遍 历 一 遍 操 作 后 可 得 将1*2+4*6-8/4-2经过遍历一遍操作后可得 12+468/42
操 作 后 结 果 : 2 + 24 − 2 − 2 操作后结果:2+24-2-2 2+2422

这个结果是存储在我们之前定义的运算符栈和操作数栈中的,很明显会发现,因运算符都是双目运算符,固最后剩余运算数的个数要比操作符的个数多一个。最终只需从前往后计算即可。

上代码:

#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 500010;
char op[N];
double num[N];
int s, t;
int main()
{
	string str1,str;
	getline(cin, str1);
	int len = str1.size();
    for(int i=0;i<len;i++)
    {
        if(str1[i]!=' ')
        {
            str+=str1[i];
        }
    }
    len = str.size();
	for (int i = 0;i < len;i++)
	{
        if(str[i]==' ') continue;
		if (str[i] >= '0' && str[i] <= '9')
		{
			int j = i;
			double sum = 0;
			while (str[j] >= '0' && str[j] <= '9' && j < len)
			{
				sum = sum * 10 + str[j] - '0';
				j++;
			}
			num[++s] = sum * 1.0;
			i = j - 1;
		}
		else {
			if (str[i] == '*' || str[i] == '/')
			{
				op[++t] = str[i];
			}
			else {
				int j = i + 1;
				double sum = 0;
				while (str[j] >= '0' && str[j] <= '9' && j < len)
				{
					sum = sum * 10 + str[j] - '0';
					j++;
				}
				if (str[i] == '+')
				{
					if (sum < 1e-6)
					{
						puts("Cannot be divided by 0");
						return 0;
					}
					else num[s] /= sum;
				}
				else if (str[i] == '-')
				{
					num[s] *= sum;
				}
				i = j - 1;
			}
		}
	}
	double ans = num[1];
	for (int i = 1;i <= t;i++)
	{
		if (op[i] == '*')
		{
			ans -= num[i + 1];
		}
		else ans += num[i + 1];
	}
	printf("%.2lf", ans);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值