<数据结构经典题> c++实现用栈进行对表达式的计算代码以及代码解析

我们对表达式进行计算,关键是如何整理运算符的顺序,我们对每个运算符设定了一个值。

栈外运算符的值比栈内的值大的 就能压下去,栈外运算符的值比较小不能压下去,要把栈内的元算符Pop出来,然后再比较大小。
同一个运算符栈内的值要比栈外的值大,这样就能保证让同层次的运算符压不进去,让栈内的运算符先运算。

/******************************************************************************************************************
* Copyright (C): 随便copy....遵守那个啥GPL协议什么的
* @file       : main.cpp
* @brief      : 实现数据结构中栈在表达式求值
* @autor      : mikkkkk
* @date       : 2021/5/4 祝五四青年节快乐
******************************************************************************************************************/


#include <iostream>
#include <stack>
#include <map>

/*
 *
 * 1. 需要两个栈 一个map
 *
 * 2. 边输入 边计算 直接根据输入的决定 压入哪个栈
 *
 *  例子1:
 *    输入  1-(1/2)#
 *    输出  # (最开头的那个 #)
 *         0.5 (答案)
 *  例子2:
 *    输入 1*2*(5-6)+1#
 *    输出   #
 *           -1
 *    note: 输入的时候 数字只能输入 整数,感觉有待改进...
 *
 * */

using namespace std;


double calulate(double Tem1, double Tem2, char Opr)
{

    switch (Opr)
    {
        case '+':
            return Tem1 + Tem2;
        case '-':
            return Tem1 - Tem2;
        case '*':
            return Tem1 * Tem2;
        case '/':
            return Tem1 / Tem2;

    }


}

int main()
{
    //optr 是运算符  opnd是数字

    stack<char> OPTR;
    stack<double> OPND;
    //RankIsp 栈内排名 ,RankIcp 栈外排名
    map<char, int> RankIsp, RankIcp;
	//在最头的位置 加 # ,和最后结束时的 # 对应。
    OPTR.push('#');

    //栈外对运算符的赋值
    RankIcp.insert(std::pair<char, int>('#', 0));
    RankIcp.insert(std::pair<char, int>('(', 6));
    RankIcp.insert(std::pair<char, int>('*', 4));
    RankIcp.insert(std::pair<char, int>('/', 4));
    RankIcp.insert(std::pair<char, int>('+', 2));
    RankIcp.insert(std::pair<char, int>('-', 2));
    RankIcp.insert(std::pair<char, int>(')', 1));
    //栈内对运算符的赋值
    RankIsp.insert(std::pair<char, int>('#', 0));
    RankIsp.insert(std::pair<char, int>('(', 1));
    RankIsp.insert(std::pair<char, int>('*', 5));
    RankIsp.insert(std::pair<char, int>('/', 5));
    RankIsp.insert(std::pair<char, int>('+', 3));
    RankIsp.insert(std::pair<char, int>('-', 3));
    RankIsp.insert(std::pair<char, int>(')', 6));


    while (1)
    {

        char temp;
        cin >> temp;


        if (temp == '+' || temp == '-' || temp == '/' || temp == '*' \
 || temp == '(' || temp == ')' || temp == '#')
        {
            //下面判断栈内和栈外的比如 如果栈外的大 就进去
            while (1)
            {
                if (RankIcp[temp] > RankIsp[OPTR.top()])
                {
                    OPTR.push(temp);
                    break;
                } else if (RankIcp[temp] == RankIsp[OPTR.top()])
                {
                    if (temp == '#') break;
                    if (temp == ')')
                    {
                        OPTR.pop();
                        break;
                    }

                } else
                {
                    double temp1, temp2, ans;
                    char Opr;

                    temp1 = OPND.top();
                    OPND.pop();
                    temp2 = OPND.top();
                    OPND.pop();

                    Opr = OPTR.top();
                    OPTR.pop();
                    //注意是前面的那个数字 对后面的数字的计算
                    ans = calulate(temp2, temp1, Opr);

                    OPND.push(ans);
                    continue;
                }
            }
        } else
        {             //这一步得到只是整数,所以只有整数push进操作数栈内,才能保证运算正确
            OPND.push((double) temp - 48);

        }
        if (temp == '#')
            break;

    }


    while (!OPTR.empty())
    {
        cout << OPTR.top();
        OPTR.pop();
    }
    cout << endl;
    while (!OPND.empty())
    {
        cout << OPND.top();
        OPND.pop();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值