CSU 文本计算器

文本计算器

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 37   Solved: 12
[ Submit][ Status][ Web Board]

Description

Bob讨厌复杂的数学运算.
看到练习册上的算术题,Bob很是头痛.
为了完成作业,Bob想要你帮忙写一个文本版的四则运算计算器.
这个计算器的功能需求十分简单,只要可以处理加减乘除和括号就可以了.
你能够帮助Bob吗?

Input

每个样例一行,输入一个长度小于1500的包含有'(',')','+','-','*','/',和'1'~'9'组成的四则运算表达式.
对于每个样例,参与运算数字在0~10000之间,表达式运算的结果在double的表示范围内.

Output

对于每一个例子,输出表达式的计算结果,精确到小数点后4位

Sample Input

3928*3180*3229+2137
2477*8638
1535+7452+3780+2061*280/3070/(7828-9348)

Sample Output

40333570297.0000
21396326.0000
12766.8763


模拟计算器计算

注意优先级 注意精度

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#include <stack>

#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 10010
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)

using namespace std;

#define maxn 2000
char buf[maxn];
int length;

stack<char> op;
stack<double> n;

int getPriority(char c)
{
    switch(c)
    {
        case '(': return 1;
        case ')': return 1;
        case '+': return 2;
        case '-': return 2;
        case '*': return 3;
        case '/': return 3;
        default: return 0;
    }
}

double calc(double a,double b,char c)
{
    double d;
    switch(c)
    {
        case '+': d=(a+b); break;
        case '-': d=(a-b); break;
        case '*': d=(a*b); break;
        case '/': d=(a/b); break;
    }
    return d;
}
void pull()
{
    double a,b;
    char c=op.top(); op.pop();
    if(getPriority(c)>1 && n.size()>1){
        b=n.top(); n.pop();
        a=n.top(); n.pop();
        n.push(calc(a,b,c));
    }
}


int main()
{
//    fread;
    while(scanf("%s",buf)!=EOF)
    {
        char c; double d; int i;
        length=strlen(buf);
        i=-1;
        while(++i<length)
        {
            if( buf[i]=='-' ){  //  '-' 可能出现二义性(符号或减号)因此特殊处理
                int flag=0;
                if(i==0) flag=1;
                else if(i>0){
                    int tmp=i;
                    flag=1;
                    while(tmp--){
                        if(isalnum(buf[tmp])){
                            flag=0; break;
                        }else if(getPriority(buf[tmp])>1) break;
                    }
                }

                if(flag){
                    sscanf(buf+i,"%lf",&d); n.push(d);
                    while(isalnum(buf[i+1]) || '.'==buf[i+1]) i++;
                    continue;
                }
            }

            if(isalnum(buf[i])){
                //从左至右扫描表达式,数字读入
                sscanf(buf+i,"%lf",&d); n.push(d);
                while(isalnum(buf[i+1]) || '.'==buf[i+1]) i++;
            }else{
                //从左至右扫描表达式,运算符读入
                c=buf[i];
                if(getPriority(c)){
                    //能被识别的操作符
                    if('('==c || op.empty() || getPriority(c)>getPriority(op.top()) ) op.push(c);
                    else if(')'==c){
                        //遇到有括号退栈计算,直到计算到左括号或栈空为止
                        while(!op.empty() && '('!=op.top()) pull();
                        if(!op.empty()) op.pop();
                    }else{
                        while(!op.empty() && getPriority(c)<=getPriority(op.top())) pull();  //操作符计算
                        op.push(c);
                    }
                }
            }
        }

        while(!op.empty()) pull();
        printf("%.4lf\n",n.top());
        while(!n.empty()) n.pop();  //清空数据栈
    }
    return 0;
}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值