栈的应用-简单计算器

/*
2*(3+4)
234+*

*/
#include<bits/stdc++.h>
using namespace std;
stack<char> s,s2;
string str,ret;
int priority(char c)
{
    if(c=='(') return 1;
    else if(c=='+') return 2;
    else if(c=='-') return 2;
    else if(c=='*') return 3;
    else if(c=='/') return 3;
    else if(c==')') return 4;
    else return -1;
}
void change(string str)
{
    int i=0;
    while(str[i]!='\0'){
        if(str[i]>='0'&&str[i]<='9'){
            ret+=str[i];
        }
        else if(str[i]=='(')
        {
            s.push(str[i]);
        }
        else if(str[i]==')')
        {
            while(s.top()!='(')
            {
                ret+=s.top();
                s.pop();
            }
            if(s.top()=='(')
                s.pop();
        }
        else if(s.empty() || priority(str[i]) > priority(s.top()))
        {
            s.push(str[i]);
        }
        else{
            while(priority(str[i])<=priority(s.top()))
            {
                ret+=s.top();
                s.pop();
            }
            s.push(str[i]);
        }
        i++;
    }
    while(!s.empty())
    {
        ret+=s.top();
        s.pop();
    }
}

int cal(string ret)
{
    int i=0;
    while(ret[i]!='\0')
    {
        if(ret[i]>='0'&&ret[i]<='9')
        {
            s2.push(ret[i]);
        }
        else if(ret[i]=='+')
        {
            int a=s2.top()-'0';
            s2.pop();
            int b=s2.top()-'0';
            s2.pop();
            s2.push(a+b+'0');

        }
        else if(ret[i]=='-')
        {
            int a=s2.top()-'0';
            s2.pop();
            int b=s2.top()-'0';
            s2.pop();
            s2.push(b-a+'0');

        }
        else if(ret[i]=='*')
        {
            int a=s2.top()-'0';
            s2.pop();
            int b=s2.top()-'0';
            s2.pop();
            s2.push(a*b+'0');

        }
        else if(ret[i]=='/')
        {
            int a=s2.top()-'0';
            s2.pop();
            int b=s2.top()-'0';
            s2.pop();
            s2.push(b/a+'0');

        }
        i++;
    }
    return s2.top()-'0';
}
int main()
{
    cin >> str;
    change(str);
    cout << ret << endl;
    cout << cal(ret) << endl;
    return 0;
}

理论分析:

数据结构–中缀表达式转为后缀表达式(逆波兰表达式)

中缀表达式是一个通用的算术或逻辑公式表示方法。操作符是以中缀形式处于操作数中间。例如:3*4+3-1;

后缀表达式不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右(不再考虑运算符的优先规则)例如:(2+1)*3,即2 1 + 3 *

(以上来自百度百科)

具体的代码实现:代码实现中缀转后缀表达式

1.中缀表达式转为后缀表达式

想要完成此过程需要一个数组arr存放中缀表达式,一个ret 存放后缀表达式,还要借助一个辅助栈stack1存放操作符,stack2存放运算结果。

规则:

从左到右一次遍历中缀表达式,如果是数字就直接存放到后缀表达式中;

如果是操作符,例如操作符A,需要将A于操作符栈stack1的栈顶操作符比较,如果stack1为空或栈顶操作符优先级低于A,将A压入stack1.

如果A的优先级低于或等于stack1栈顶的操作符的优先级,把栈顶操作符pop出栈,存到ret 中,然后继续与A比较,重复此前动作直到A入栈。

注意:

操作符’(‘和’)’ 比较特殊。如果是’(’ 直接入栈stack1;如果是‘)’ 需要将stack1的操作符pop到ret中,直到弹出’(’;

重复以上工作,直到把操作符栈stack1中的操作符全部弹出到ret中;这样就把中缀表达转化为后缀表达式;

例如:

中缀表达式:3*1+(4+6)/2-1

第一步:取3,ret[ 3 ] , stack1[ ];

第二步:取*, ret[3] , stack1 [ * ];

第三步: 取1 ,ret[3,1] , stack1 [ * ];

第四步,取+,ret[3,1,*] , stack1 [ + ];

第五步:取(, ret[3,1,*] , stack1 [ + ,( ];

第六步:取4, ret[3,1,*,4] , stack1 [ + ,( ];

第七步:取+, ret[3,1,*,4] , stack1 [ + ,( ,+ ];

第八步:取6,ret[3,1,*,4, 6] , stack1 [ + ,( ,+ ];

第九步:取), ret[3,1,*,4, 6,+] , stack1 [ + ];

第十步:取/, ret[3,1,*,4, 6,+] , stack1 [ + ,/ ];

第十一步:取2,ret[3,1,*,4, 6,+,2] , stack1 [ + ,/ ];

第十二步:取-, ret[3,1,*,4,6,+,2,/, + ] , stack1 [ - ];

第十三步:取1,ret[3,1,*,4,6,+,2,/,+,1 ] , stack1 [ - ];

处理stack1: ret[3,1,*,4, 6,+,2,/, +,1 ,- ] , stack1 [ ];

所以后缀表达式为:3,1,*,4, 6,+,2,/, +,1 ,- ;

2.利用后缀表达式计算结果

规则:遍历储存后缀表达式的列表,将元素依次进栈,当遇到操作符时,连续出栈两个元素,进行运算,再将结果进栈,最后栈内留下的元素就是计算结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/w1304636468/article/details/89413139
今日推荐