zoukankan      html  css  js  c++  java
  • 栈------表达式求值

    栈的应用---表达式求值

    1.简单计算器

    Problem Description
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
     
    Input
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
     
    Output
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
     
    Sample Input
    1 + 2 4 + 2 * 5 - 7 / 11 0
     
    Sample Output
    3.00 13.36
     
    Source
    #include <iostream>
    #include <stack>
    #include <string>
    #include <cstdio>
    using namespace std;
    
    stack<double> opnd; //运算对象栈
    stack<char> optr;   //运算符号栈
    void f()            //取栈顶元素运算
    {
        double tmp;
        char key=optr.top();
        optr.pop();
        double x=opnd.top();
        opnd.pop();
        double y=opnd.top();
        opnd.pop();
        switch(key)
        {
        case '+': tmp=x+y;  break;
        case '-': tmp=y-x;  break;
        case '*': tmp=x*y;  break;
        case '/': tmp=y/x;  break;
        }
        opnd.push(tmp);
    }
    int main()
    {
        double a,ans=0;
        char t,b;
        while(scanf("%lf",&a)==1)
        {
            opnd.push(a);
            scanf("%c",&t);
            if(a==0&&t=='
    ')           //结束循环
                break;
            while(scanf("%s %lf",&b,&a)==2)
            {
                char ch=getchar();      //读入数字后面的字符
                while(1)
                {
                    if(optr.empty()||((b=='*'||b=='/')&&(optr.top()=='+'||optr.top()=='-')))
                    {
                        optr.push(b);           //栈空或下一个运算符优先级更高,入栈
                        opnd.push(a);
                        break;
                    }
                    else                        //否则取栈顶元素运算然后运算符入栈
                         f();
                }
                if(ch=='
    ')                 //输出结果
                {
                    while(!optr.empty())
                    {
                        f();
                    }
                    ans=opnd.top();
                    printf("%.2lf
    ",ans);
                    while(!opnd.empty())    //多组测试数据,清空栈
                    {
                        opnd.pop();
                    }
                    while(!optr.empty())
                    {
                        optr.pop();
                    }
                    break;
                }
            }
        }
        return 0;
    }

     这题至少整了两天,一开始是为了练一练STL,熟悉熟悉应用的,然后发现数据结构教科书上P87的例题写错了,只能进行10以内的加减乘除运算,除法还没法保持精度,然后这题一开始敲的时候就是整体将表达式读入,再处理的,没有注意到题中的每个符号之间都有一个空格,这能很好的简化题目,否则就得考虑字符串转化为数字的处理,手动模拟数字乘位权值;(这里,题目也没给清楚表达式里数字的范围,= =有想到java的大数浮点型)。最后终于AC了。。。

    2.POJ2106 Boolean Expressions

    Description

    The objective of the program you are going to produce is to evaluate boolean expressions as the one shown next: 
    Expression: ( V | V ) & F & ( F | V )

    where V is for True, and F is for False. The expressions may include the following operators: ! for not , & for and, | for or , the use of parenthesis for operations grouping is also allowed. 

    To perform the evaluation of an expression, it will be considered the priority of the operators, the not having the highest, and the or the lowest. The program must yield V or F , as the result for each expression in the input file. 

    Input

    The expressions are of a variable length, although will never exceed 100 symbols. Symbols may be separated by any number of spaces or no spaces at all, therefore, the total length of an expression, as a number of characters, is unknown. 

    The number of expressions in the input file is variable and will never be greater than 20. Each expression is presented in a new line, as shown below. 

    Output

    For each test expression, print "Expression " followed by its sequence number, ": ", and the resulting value of the corresponding test expression. Separate the output for consecutive test expressions with a new line. 

    Use the same format as that shown in the sample output shown below. 

    Sample Input

    ( V | V ) & F & ( F| V)
    !V | V & V & !F & (F | V ) & (!F | F | !V & V)
    (F&F|V|!V&!F&!(F|F&V))

    Sample Output

    Expression 1: F
    Expression 2: V
    Expression 3: V

    Source

    #include <iostream>
    #include <stack>
    #include <string>
    #include <cstdio>
    using namespace std;
    int main()
    {
        string s;
        int kase=1;
        //freopen("Atext.in","r",stdin);
        while(getline(cin,s)){
            int x,y,c;
            stack<int> val;
            stack<char> op;
            for(int i=0;i<s.size();i++){
                switch(s[i])
                {
                case '(':
                    op.push(s[i]);
                    break;
                case '!':       //注意如:!!!F,一开始没处理好RE了;
                    if(!op.empty()&&op.top()=='!'){
                        op.pop();//注意!为单目运算符,一开始没处理好!
                    }else
                        op.push(s[i]);
                    break;
                case '|':
                case '&':
                case ')':
                    while(!op.empty()){
                        if(op.top()=='!'){
                        x=val.top();
                        val.pop();
                        val.push((!x));
                        op.pop();
                        }else if(op.top()=='|')
                        {
                            x=val.top();
                            val.pop();
                            y=val.top();
                            val.pop();
                            val.push((x|y));
                            op.pop();
                        }else if(op.top()=='&')
                        {
                            x=val.top();
                            val.pop();
                            y=val.top();
                            val.pop();
                            val.push((x&y));
                            op.pop();
                        }else
                            break;
                    }
                    if(s[i]==')')
                        op.pop();
                    else
                        op.push(s[i]);
                    break;
                case 'V':
                    val.push(1);
                    break;
                case 'F':
                    val.push(0);
                    break;
                default :
                    break;
                }
            }
            while(!op.empty()){
                    if(op.top()=='!'){
                    x=val.top();
                    val.pop();
                    val.push((!x));
                    op.pop();
                }else if(op.top()=='|')
                {
                    x=val.top();
                    val.pop();
                    y=val.top();
                    val.pop();
                    val.push((x|y));
                    op.pop();
                }else if(op.top()=='&')
                {
                    x=val.top();
                    val.pop();
                    y=val.top();
                    val.pop();
                    val.push((x&y));
                    op.pop();
                }
            }
           // cout << val.size() << endl;
            //cout << op.size() << endl;
            printf("Expression %d: ",kase++);
            if(val.top()==1)
                printf("V
    ");
            else
                printf("F
    ");
        }
        return 0;
    }
    //新运算符比栈顶元素优先级高,入栈否则栈顶元素出栈运算,
    //直至栈顶元素运算符优先级低于要入栈的运算符或栈空;
  • 相关阅读:
    证书生成加密码解密
    弄懂JDK、JRE和JVM到底是什么 关系区别
    java异常中throw和throws的区别
    SpringBoot日志logback-spring.xml分环境log4j logback slf4j区别 springboot日志设置
    MD5加密的Java实现
    微服务平台(Micro Service Platform : MSP)旨在提供一个集开发、测试、运维于一体的开发者专属平台,让开发者能快速构建或使用微服务,让开发更简单,让运维更高效。
    CustomJsonDateDeserializer @JsonDeserialize(using = CustomJsonDateDeserializer.class) Jackson 反序列化Date时遇到的问题 java中json日期属性反序列化
    Gitlab用户在组中有五种权限:Guest、Reporter、Developer、Master、Owner
    用IDEA生成javadoc文档
    AB Test 是什么
  • 原文地址:https://www.cnblogs.com/Cloud-king/p/8453703.html
Copyright © 2011-2022 走看看