14.表达式求值的综合应用

#include<iostream>
#include<string>
#include<stack>
#include<cmath>
using namespace std;
int calc(string s) {
	stack<int> sum;
	char sign = '+';
	int cur = 0, ans = 0;
	int f = 1;
	for (int i = 0; i < s.size(); i++) {
		//将连续数字字符串转换为数字
		if (s[i] >= '0' && s[i] <= '9') cur = cur * 10 + s[i] - '0';
		if (f == -1) {
			cur *= f;
			f = 1;
		}
		//递归处理括号内的表达式
		if (s[i] == '(') {
			//括号匹配
			int l = i, cnt = 1;//统计净左括号的数量(遇到左括号cnt++,遇到右括号cnt--)
			i++;//向后查找与之匹配的右括号
			while (cnt > 0) {
				if (s[i] == '(') cnt++;
				else if (s[i] == ')') cnt--;
				i++;
			}
			int r = --i;
			cur = calc(s.substr(l + 1, r - l - 1));
		}
		if (i == s.size() - 1 || s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
			if (s[i] == '-' && (s[i - 1] == '/'|| s[i - 1] == '*')) {
				sign = s[i-1];
				cur = 0;
				f = -1;
				continue;
			}
			if (sign == '+') sum.push(cur);
			else if (sign == '-') sum.push(-cur);
			else if (sign == '*') sum.top() *= cur;
			else if (sign == '/') sum.top() /= cur;
			else if (sign == '^') sum.top() = pow(sum.top(), cur);
			sign = s[i];
			cur = 0;
			f = 1;
		}
	}
	while (!sum.empty()) {
		ans += sum.top();
		sum.pop();
	}
	return ans;
}
bool check(string s) {
	string opt1 = "+/*";
	//本题的第一条合法性判定:首元素不能是+/*
	if (opt1.find(s[0]) != -1) return false;//不合法
	string opt2 = "+-/*";
	//本题的第二条合法性判定:首元素不能是+/*
	if (opt2.find(s[s.size() - 2]) != -1) return false;//不合法
	int cnt = 0;
	string t;
	//本题的第三条合法性判定:括号匹配(本题特殊,只需要判定括号数量)
	for (int i = 0; i < s.size() - 1; i++) {
		if (s[i] == '(') cnt++;
		else if (s[i] == ')') cnt--;
		else t += s[i];//得到去括号后的s串即为t
	}
	if (cnt != 0) return false;
	//本题的第四条合法性判定:检查相邻运算符
	for (int i = 1; i < t.size(); i++) {
		if ((opt2.find(t[i - 1]) != -1) && (opt1.find(t[i]) != -1)) {
			return false;
		}
	}
	return true;
}
int main() {
	string s;
	getline(cin, s);
	if (!check(s)) {
		cout << "NO" << endl;
		return 0;
	}

	cout << calc(s) << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值