zoukankan      html  css  js  c++  java
  • 模拟初级计算器 单调栈实现

    题意:求解一串不出现数学公式只含'+','-','*','/', '(' , ')'的计算表达式,输出结果;

    其中'/'是带小数的除法。并且输入的数值位double型,若是输入的运算符有误,或者出现除0错误,则直接输出intput error.

    输入时除数值之间不能出现空格外,其他地方均能有空格。并且3(...)看成为3*(); 0.5也可以输入为.5;

    注意:代码中目前没有加入识别是减号还是符号的处理;所以只能处理非负整数之间的运算;

    实现细节:以运算符的优先级来设置一个优先级(数学意义)递减的单调栈。但是给予'(' ,')'不一样的优先级;即栈中实际上只是存储的是'+','-'运算,'*','/'运算会计算出数值;没遇到一个')'。表示计算与前一个'('之间的所有值;最后加发')'为了全部计算完。

    ps:由于只是随便写的,要是发现bug直接指出即可;

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<cmath>
    #define esp 1e-7
    using namespace std;
    char s[3000],op[1000];
    double v[1000];
    map<char,int> mp;
    bool solve()
    {
        mp['*'] = 1,mp['/'] = 1,mp['+'] = 2,mp['-'] = 2,mp['('] = 3, mp[')'] = 4;//维护一个单调递增的栈;
        int len = strlen(s),stk = 0,top = 0;
        s[len++] = ')';
        op[++stk] = '(';
        for(int i = 0;i < len;i++)if(s[i] != ' '){//容许输入有空格;
            if(s[i] != '.' && s[i] < '0' || s[i] > '9'){//可能输入的小数位 .5 即0.5
                if(mp.find(s[i]) == mp.end()) return false;
                while(stk >= 1 && mp[op[stk]] < mp[s[i]] && s[i] != '('){
                    if(stk == 1 && i != len - 1) return false;
                    if(s[i] == ')' && op[stk] == '('){stk--; break;}
                    if(op[stk] == '+') v[top-1] += v[top];
                    else if(op[stk] == '-') v[top-1] -= v[top];
                    else if(op[stk] == '*') v[top-1] *= v[top];
                    else if(op[stk] == '/')
                        if(fabs(v[top]) < esp) return false;//除0;
                        else v[top-1] /= v[top];
                    top--;stk--;
                }
                if(s[i] != ')')
                    op[++stk] = s[i];
            }
            else{
                double val = 0.0,f = 1;
                if(s[i] == '.') f /= 10,i++;
                for(;s[i] >= '0' && s[i] <= '9';i++){//小数不能写成 .1这样的形式;
                    if(f == 1){
                        val = val*10 + (s[i]-'0');
                    }
                    else{
                        val += f*(s[i] - '0');
                        f /= 10;
                    }
                    if(s[i+1] == '.') f = 0.1,i++;
                    if(f < 1 && s[i+1] == '.')    return false;//出现多个小数点
                }
                if(s[i--] == '(') op[++stk] = '*';// 3(2 - 4) = 3*(2 - 4)
                v[++top] = val;
            }
        }
        return stk?false:true;//最终符号栈中没有一个符号
    }
    int main()
    {
        while(gets(s), strlen(s)){
            if(solve()) printf("%f
    ",v[1]);
            else puts("input error");
        }
    }
  • 相关阅读:
    hadoop02---高可用网站架构
    springboot-vue项目前台2
    Java Serializable(序列化)
    JAVA 正则表达式、汉字正则、 java正则代码
    MyEclipse导入Maven项目
    JAVA学习:maven开发环境快速搭建
    删除
    关于java程序打包为EXE的若干问题
    ServletContext与ServletConfig的详解及区别
    在CSS中定义a:link、a:visited、a:hover、a:active顺序
  • 原文地址:https://www.cnblogs.com/hxer/p/5294845.html
Copyright © 2011-2022 走看看