HDU1237(表达式求值)

Problem

读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

Input

测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。

Output

对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。

Sample Input

1 + 2
4 + 2 * 5 - 7 / 11
0

Sample Output

3.00
13.36

思路

中缀表达式转后缀,再求值即可

具体见:https://blog.csdn.net/Feynman1999/article/details/64912591

code

#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <vector>
#include <algorithm>

using namespace std;
typedef long long ll;
vector<string> ans;
vector<string> thought_opera = { "+", "-", "*", "/", "(", ")" };
short Priority[5] = { 0,0,1,1,-1 };

bool is_opera(string tp) {
	if (tp == "+" || tp == "-" || tp == "*" || tp == "/" || tp == "(" || tp == ")")  return true;
	return false;
}

ll string_to_num(string tp) {
	ll flag = 1;
	if (tp[0] == '-') {
		flag = -1;
		tp = tp.substr(1);
	}
	ll num = 0;
	for (int i = 0; i < tp.length(); ++i) {
		num *= 10;
		num += tp[i] - '0';
	}
	return flag * num;
}

int main()
{
	//freopen("in.txt", "r", stdin);
	string s;
	while (getline(cin, s)) {
		if (s == "0") break;
		ans.clear();
		stack<string> opera;
		stringstream scin(s);
		string tmp;
		while (scin >> tmp)
		{
			if (is_opera(tmp)) {
				if (tmp == ")") {
					while (opera.top() != "(")//数据保证一定有(
					{
						ans.push_back(opera.top());
						opera.pop();
					}
					opera.pop();//括号不用输出
				}
				else if (tmp == "(") {
					opera.push(tmp);
				}
				else {
					short id1 = find(thought_opera.begin(), thought_opera.end(), tmp) - thought_opera.begin();
					while (!opera.empty())
					{
						short id2 = find(thought_opera.begin(), thought_opera.end(), opera.top()) - thought_opera.begin();
						if (Priority[id1] <= Priority[id2]) {
							ans.push_back(opera.top());
							opera.pop();
						}
						else {
							break;
						}
					}
					opera.push(tmp);
				}
			}
			else {
				ans.push_back(tmp);// is number
			}
		}
		while (!opera.empty())
		{
			ans.push_back(opera.top());
			opera.pop();
		}
		//for (auto k : ans) {
		//	cout << k << " ";
		//}
		stack<double> number;//由逆波兰表达式求值
		for (auto k : ans) {
			if (is_opera(k)) {
				double number1 = number.top();
				number.pop();
				double number2 = number.top();
				number.pop();
				if (k == "-") {
					number.push(number2 - number1);
				}
				else if (k == "+") {
					number.push(number2 + number1);
				}
				else if (k == "*") {
					number.push(number2 * number1);
				}
				else {//  "/"
					number.push(number2 / number1);
				}
			}
			else {
				number.push(string_to_num(k));
			}
		}
		printf("%.2f\n", number.top());
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值