• hdu 1237 简单计算器 栈


    这个题目是大部分人都是用栈来写的,本周训练老师也讲了两次栈的原理。自己最近也看了数据结构中与栈有关的内容,还是比较深刻理解了没有括号情况下表达式求解。

    #include<stdio.h>
    #include<string.h>
    #include<stack>
    using namespace std;
    
    char s[250],post[250];//s是输入的中缀表达式,post是转化出来的后缀表达式
    stack<char>op;//存放运算符
    stack<double>num;//存放运算过程中的数字
    
    int isnum(char c)//判断字符是否为数字
    {
        if(c>='0'&&c<='9')
            return 1;
        return 0;
    }
    
    double opmode(char c)//运算符优先级判定
    {
        if(c=='+') return 1;
        if(c=='-') return 2;
        if(c=='*') return 3;
        if(c=='/') return 4;
        return -1;
    }
    
    void change()//将中缀表达式转化为后缀表达式
    {
        int i,j=0,len;
        memset(post,0,sizeof(post));
        len=strlen(s);
        for(i=0; i<len; i++)
        {
            if(s[i]==' ') continue;
            post[j++]=' ';//空格是关键,主要是区分数字用的,出现俩个连续的1会当成11,而不是两个1
            while(isnum(s[i])) post[j++]=s[i++];
            int c=opmode(s[i]);
            //当前运算的与栈顶运算符号进行比较
            if(c!=-1)
            {
                if(c<=2)//优先级小于等于栈顶的运算符时,将栈顶的运算符输入到数组中
                {
                    while(!op.empty())//因为+-遇到任何一个栈内符号都会小于或等于,所以将所有运算符输出
                    {
                        post[j++]=op.top();
                        op.pop();
                    }
                }
                else
                {
                    while(!op.empty()&&opmode(op.top())>2)//栈顶运算符是*/时,才将栈顶的输出
                    {
                        post[j++]=op.top();
                        op.pop();
                    }
                }
                op.push(s[i]);//优先级大时或者上面操作后将当前运算符入栈
            }
        }
        while(!op.empty())//对象处理完毕将栈中存留的运算符一并输出
        {
            post[j++]=op.top();
            op.pop();
        }
    }
    
    double cal()//计算后缀表达式
    {
        while(!num.empty()) num.pop();//清空栈
        int i=0,len;
        len=strlen(post);
        for(i=0;i<len;i++)
        {
            if(post[i]==' ') continue;
            double cur=0;
            bool hasnum=0;
            while(isnum(post[i]))//提取数字
            {
                cur*=10;
                cur+=post[i]-'0';
                hasnum=1;
                i++;
            }
            if(hasnum) num.push(cur);
            if(opmode(post[i])!=-1)//遇到运算符,提取栈顶两个数字进行计算
            {
                double n1=num.top();
                num.pop();
                double n2=num.top();
                num.pop();
                switch(post[i])
                {
                    case '+':num.push(n1+n2);break;
                    case '-':num.push(n2-n1);break;
                    case '*':num.push(n1*n2);break;
                    case '/':num.push(n2/n1);break;
                }
            }
        }
        return num.top();//输出答案
    }
    
    int main()
    {
        while(gets(s))
        {
            if(strcmp(s,"0")==0) break;
            change();
            printf("%.2f
    ",cal());
        }
        return 0;
    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。http://xiang578.top/

  • 相关阅读:
    BZOJ2962: 序列操作
    BZOJ2037: [Sdoi2008]Sue的小球
    LOJ#2537. 「PKUWC2018」Minimax
    LOJ#2538. 「PKUWC2018」Slay the Spire
    BZOJ4756 [USACO17JAN]Promotion Counting晋升者计数
    BZOJ2212——线段树合并
    atcoder.keyence2019.contest E-Connecting Cities
    [转载]笛卡尔树
    大数模板
    点分治
  • 原文地址:https://www.cnblogs.com/xryz/p/4848061.html
Copyright © 2020-2023  润新知