zstuoj 2853 算术表达式 模拟

题目链接:http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=2853

题意:

给你一个算数表达式,保证正确,让你求出结果。

思路:

长度只有150,暴力模拟递归。

1.若字符串s最外层存在加减号,则处理加减号。(注意首字符为减号的情况)

2.1不成立,则找最外层的乘除号。

3. 1、2均不成立,则检查整个字符串是否被一个()给包含了,是则去掉括号然后递归。

4.1、2、3不成立,则说明这是一个整数,直接sscanf函数求出,返回即可。

×何为最外层,就是没有被任何括号给包含进去的,则是最外层。


以前课程上做过算数表达式的题,不过是建立二叉树的形式,网上也有将中缀式变为后缀式的做法。

不过在ACM中100~200的直接暴力模拟即可。

这里主要是为了存个模板。

code:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;

double deal(string s) {
	double ret = 0;
	//'+', '-'
	int mark = 0;
	bool flag = false;
	int last = -1;//last index;
	for(int i=0;i<s.length();i++){
		if(mark==0&&(s[i]=='-'||s[i]=='+')){
			flag = true;
			if(i == 0)
				ret = 0, last = 0;
			else {
				if(last==-1) 
					ret = deal(s.substr(0, i));
				else {
					double tmp = deal(s.substr(last+1, i-last-1));
					if(s[last]=='-') tmp = -tmp;
					ret += tmp;
				}
				last = i;
			}
		}
		else if(s[i]=='(') mark++;
		else if(s[i]==')') mark--;
	}
	if(flag) {
		double tmp = deal(s.substr(last+1));
		if(s[last] == '-') tmp = -tmp;
		ret += tmp;
		return ret;
	}
	//'*','/'
	flag = false;
	mark = 0, last = -1;
	for(int i = 0;i < s.length(); i++) {
		if(mark==0&&(s[i]=='*'||s[i]=='/')) {
			flag = true;
			if(last == -1) 
				ret = deal(s.substr(0, i));
			else {
				double tmp = deal(s.substr(last+1, i-last-1));
				if(s[last]=='*') ret *= tmp;
				else ret /= tmp;
			}
			last = i;
		}
		else if(s[i]=='(') mark++;
		else if(s[i]==')') mark--;
	}
	if(flag) {
		double tmp = deal(s.substr(last+1));
		if(s[last] == '*') ret *= tmp;
		else ret /= tmp;
	}
	if(flag) return ret;
	//()
	if(s[0] == '(') return deal(s.substr(1, s.length()-1));
	//single number
	sscanf(s.c_str(), "%lf", &ret);
	return ret;
}

int main() {
	string s;
	while(cin>>s)
		printf("%.4f\n", deal(s));
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值