表达式求值(C++,中缀转后缀,再后缀求值)

中缀表达式:操作数 运算符 操作数
后缀表达式:操作数 操作数 运算符
/*
思路:
使用栈将中缀表达式转化为后缀表达式:
从左到右处理各个元素,直到末尾:
(1)遇到操作数,直接加入后缀表达式
(2)遇到界限符,遇到"(“直接入栈,遇到”)“,则依次弹出栈内运算符并加入后缀表达式,直到弹出”(“为止
(3)遇到运算符,依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到”("或栈空则停止,之后再把当前运算符入栈

用栈实现后缀表达式的计算:
(1)从左往右扫描下一个元素,知道处理完所有元素
(2)若扫描到操作数则压入栈,并回到(1);否则执行(3)
(3)若扫描到运算符,则弹出栈顶元素,执行相应运算(先出栈的是右操作数),运算结果压入栈中,回到(1)

//其中,只用到了C++的常用STL,传递引用,cout输出。
//有一定局限性,必须保证输入的中缀表达式完全正确。。
*/

#include <iostream>
using namespace std;
#include <vector> //存储表达式
#include <stack>  //应用栈
#include <string>

// 判断是否为运算符
bool IsOperator(string c)
{
    if (c == "+" || c == "-" || c == "*" || c == "/")
        return true;
    else
        return false;
}

// 判断优先级
bool IsPriority(string top, string c)
{
    // 栈顶元素和当前元素比较
    if (top == "*" || top == "/") // 乘除的优先级较高不管当前是什么,都可以弹出
        return true;
    else if ((top == "+" || top == "-") && (c == "+" || c == "-")) // 剩下加减,在当前是加减的情况下,才可以弹出
        return true;
    else
        return false; // 否则不弹出栈顶元素
}

// 中缀表达式转成后缀表达式
void InfixToPostfix(vector<string> &v, vector<string> &result)
{
    stack<string> s; // 运算符暂存栈
    for (int i = 0; i < v.size(); ++i)
    {
        while ((IsOperator(v[i])) && (!s.empty()) && (IsPriority(s.top(), v[i])))
        {
            result.push_back(s.top()); // 栈顶元素加入后缀表达式
            s.pop();                   // 弹出栈顶元素}
        }
        if (IsOperator(v[i])||v[i]=="(") // 是运算符
        {
            s.push(v[i]);
        }
        else if (v[i] == ")") // 是右括号,前提条件中缀表达式完全正确
        {
            while ((!s.empty())&&(s.top() != "("))
            {
                result.push_back(s.top());
                s.pop();
            }
            s.pop(); // 左括号弹出
        }
        else
        {
            result.push_back(v[i]); // 是数字直接入后缀表达式
        }
    }
    while (!s.empty())
    {
        result.push_back(s.top());
        s.pop();
    }
}

//运算符,转运算
int Operation(int num1,int num2,string c)
{
    if(c=="+")
        return num1+num2;
    else if(c=="-")
        return num1-num2;
    else if(c=="*")
        return num1*num2;
    else if(c=="/")
        return num1/num2;
    else
        return 0;
}

// 后缀表达式的计算
int CalculationPostfix(vector<string> &v)
{
    stack<int> s; //操作数暂存栈
    for(int i=0;i<v.size();++i)
    {
        if(IsOperator(v[i]))
        {   //前提条件,仍旧是必须后缀表达式完全正确
            float num2=s.top(); 
            s.pop();
            float num1=s.top();
            s.pop();
            s.push(Operation(num1,num2,v[i]));//计算结果加入栈中
        }
        else
        {
            s.push(stoi(v[i]));//字符串转整数
        }
    }
    return s.top();
}
// 输出
void show(vector<string> &v)
{
    for (vector<string>::iterator it = v.begin(); it != v.end(); ++it)
    {
        string s = *it;
        cout << s << " ";
    }
    cout << endl;
}

// 测试
void test()
{
    vector<string> expression = {"10", "+", "2", "*", "(", "4", "-", "5", ")"}; // 10+2*(4-5)->10 2 4 5 - * +
    show(expression);
    vector<string> result;
    InfixToPostfix(expression, result);
    show(result); //ok
    int output=CalculationPostfix(result);
    cout<<output<<endl;
}

int main()
{
    test();
    return 0;
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物往fd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值