NYOJ-1272 河南省第九届ACM省赛 A题

表达式求值

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述
假设表达式定义为: 1. 一个十进制的正整数 X 是一个表达式。 2. 如果 X 和 Y 是 表达式,则 X+Y, X*Y 也是表达式; *优先级高于+. 3. 如果 X 和 Y 是 表达式,则 函数 Smax(X,Y)也是表达式,其值为:先分别求出 X ,Y 值的各位数字之和,再从中选最大数。 4.如果 X 是 表达式,则 (X)也是表达式。 例如: 表达式 12*(2+3)+Smax(333,220+280) 的值为 69。 请你编程,对给定的表达式,输出其值。  
输入
【标准输入】 第一行: T 表示要计算的表达式个数 (1≤ T ≤ 10) 接下来有 T 行, 每行是一个字符串,表示待求的表达式,长度<=1000
输出
【标准输出】 对于每个表达式,输出一行,表示对应表达式的值。
样例输入
3
12+2*3
12*(2+3)
12*(2+3)+Smax(333,220+280)
样例输出
18
60

69


这个题就是判断优先级,然后不断的压栈和出栈,细节比较繁琐,需要考虑的东西很多,这个题还有Smax函数需要处理,必须细心,仔细,考的东西不是很难。

#include <bits/stdc++.h>
using namespace std;

struct pir
{
	long long val;
	char cmd;
	pir (long long v = 130277602691393900, char c = 0) : val(v), cmd(c) {}
};
int smax(long long a, long long b)
{
	int ta = 0, tb = 0;
	while (a)
	{
		ta += a % 10;
		a /= 10;
	}
	while (b)
	{
		tb += b % 10;
		b /= 10;
	}
	return max(ta, tb);
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	//符号优先级映射
	map<char, int> mp;
	mp[','] = 0;
	mp['+'] = 1;
	mp['-'] = 1;
	mp['*'] = 2;
	mp['/'] = 2;
	mp['('] = 3;
	mp[')'] = 3;
	int t;
	cin >> t;
	for (int ti = 0; ti < t; ti++)
	{
		string str;
		getline(cin, str);
		if (str == "")
		{
			ti--;
			continue;
		}
		//行表达式空格分离
		for (int i = 0; i < str.length(); i++)
			if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' ||
				str[i] == '(' || str[i] == ')' || str[i] == ',')
			{
				str.insert(i++, 1, ' ');
				str.insert(++i, 1, ' ');
			}
			else if (str[i] == 'S')
				str.erase(i--, 4);
		if (str[str.length() - 1] == ' ')
			str.erase(str.length() - 1, 4);
		stringstream ss(str);
		stack<pir> stk;
		queue<pir> que;
		//逆波兰处理
		while (ss >> str)
		{
			if (isdigit(str[0]))
			{
				pir t;
				stringstream ss2(str);
				ss2 >> t.val;
				que.push(t);
			}
			else
				if (str[0] == ')')
				{
					while (stk.top().cmd != '(')
					{
						que.push(stk.top());
						stk.pop();
					}
					stk.pop();
				}
				else if (stk.empty() || stk.top().cmd == '(' || mp[str[0]] > mp[stk.top().cmd])
				{
					pir t;
					t.cmd = str[0];
					stk.push(t);
				}
				else
				{
					while (!stk.empty() && mp[stk.top().cmd] >= mp[str[0]] && stk.top().cmd != '(')
					{
						que.push(stk.top());
						stk.pop();
					}
					pir t;
					t.cmd = str[0];
					stk.push(t);
				}

		}
		while (!stk.empty())
		{
			que.push(stk.top());
			stk.pop();
		}
		//cout << endl;
		//栈计算
		while (!que.empty())
		{
			if (que.front().val != 130277602691393900)
				stk.push(que.front());
			else
			{
				pir t;
				long long fst = stk.top().val;
				stk.pop();
				long long lat = stk.top().val;
				stk.pop();
				switch (que.front().cmd)
				{
				case '+':
					t.val = lat + fst;
					break;
				case '-':
					t.val = lat - fst;
					break;
				case '*':
					t.val = lat * fst;
					break;
				case '/':
					t.val = lat / fst;
					break;
				case ',':
					t.val = smax(lat, fst);
					break;
				}
				stk.push(t);
			}
			que.pop();
		}
		cout << stk.top().val << endl;
	}

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值