中缀表达式求值 C++

问题描述:
在计算机中,算术表达式由常量、变量、运算符和括号组成。由于不同的运 算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行,在程序设计时,借助栈实现。

表达式求值程序分析:
主要利用栈和已知的算符优先关系,实现对算术四则运算的求值,在求值中运用栈、运算栈、输入字符和主要操作的变化过程。该程序相当于一个简单的计算机计算程序,只进行简单的加减乘除和带括号的四则运算。

概要设计:
a先乘除后加减;
b从左到右计算;
c 先括号内,后括号外。

为了实现运算符有限算法,在程序中使用了两个工作栈。
分别是:运算符栈,操作数栈.

基本思想:
1.若运算符栈没有元素则运算符直接入栈
2.若运算符栈有元素,若栈顶运算符优先级小于将要入栈的运算符,则继续入栈,否则栈顶运算符出栈且进行相应的运算操作(至少执行一次运算操作)后再将要入栈的运算符入栈
3.左括号直接入栈不需要判断,虽然栈优先级最低
4.当操作符右括号时。若栈顶运算符是左括号,则栈顶运算符出栈且右括号不入栈;若栈顶运算符不是左括号则栈顶运算符出栈执行相应的运算操作,然后出栈左括号且该右括号不入栈 【注意:一般若栈顶元素不是左括号,出一次栈后,左括号就是栈顶元素了】

程序运算符优先级安排:

int priority(string opt)
{
    int p = 0;
    if (opt == "(")
        p = 1;
    if (opt == "+" || opt == "-")
        p = 2;
    if (opt == "*" || opt == "/")
        p = 3;
    return p;
}

运算例子:
(4+3*5-(4/4+1)-3*5)
=> (4+15-(4/4+1)-3*5
=> (19-(1+1))-3*5
=> (19-2)-3*5
=> 17-3*5
=> 17-15
=> 2

代码:

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <cstdlib>

using namespace std;

int priority(string opt)
{
    int p = 0;
    if (opt == "(")
        p = 1;
    if (opt == "+" || opt == "-")
        p = 2;
    if (opt == "*" || opt == "/")
        p = 3;
    return p;
}

void calculate(stack<int> &opdstack, string opt)
{
    if (opt == "+")
    {
        int ropd = opdstack.top();
        opdstack.pop();
        int lopd = opdstack.top();
        opdstack.pop();
        int result = lopd + ropd;
        opdstack.push(result);
    }
    if (opt == "-")
    {
        int ropd = opdstack.top();
        opdstack.pop();
        int lopd = opdstack.top();
        opdstack.pop();
        int result = lopd - ropd;
        opdstack.push(result);
    }
    if (opt == "*")
    {
        int ropd = opdstack.top();
        opdstack.pop();
        int lopd = opdstack.top();
        opdstack.pop();
        int result = lopd * ropd;
        opdstack.push(result);
    }
    if (opt == "/")
    {
        int ropd = opdstack.top();
        opdstack.pop();
        int lopd = opdstack.top();
        opdstack.pop();
        int result = lopd / ropd;
        opdstack.push(result);
    }
}

int calcuExpression(vector<string> vec)
{
    stack<int> stack_opd;
    stack<string> stack_opt;

    for (auto i = 0; i != vec.size(); ++i)
    {
        string token = vec[i];
        if (token == "+" || token == "-" || token == "*" || token == "/")
        {
            if (stack_opt.size() == 0)
                stack_opt.push(token);
            else
            {
                int token_p = priority(token);
                string top_opt = stack_opt.top();
                int opt_p = priority(top_opt);
                if (token_p > opt_p)
                    stack_opt.push(token);
                else
                {
                    while (token_p <= opt_p)
                    {
                        stack_opt.pop();
                        calculate(stack_opd, top_opt);
                        if (stack_opt.size() > 0)
                        {
                            top_opt = stack_opt.top();
                            opt_p = priority(top_opt);
                        }
                        else
                            break;
                    }
                    stack_opt.push(token);
                }
            }
        }

        else if (token == "(")
            stack_opt.push(token);
        else if (token == ")")
        {
            while (stack_opt.top() != "(")
            {
                string top_opt = stack_opt.top();
                calculate(stack_opd, top_opt);
                stack_opt.pop();
            }
            stack_opt.pop();
        }
        else
            stack_opd.push(atoi(token.c_str()));//函数返回一个指向正规C字符串的指针, 内容与本string串相同
    }

    while (stack_opt.size() != 0)
    {
        string top_opt = stack_opt.top();
        calculate(stack_opd, top_opt);
        stack_opt.pop();
    }
    return stack_opd.top();
}

int main()
{
    vector<string> tokens = { "(", "4", "+", "3", "*", "5", "-", "(", "4", "/", "4", "+", "1", ")", ")", "-", "3", "*", "5" };
    for (auto i = 0; i != tokens.size(); ++i)
        cout << tokens[i] << " ";
    cout << endl;
    cout << calcuExpression(tokens) << endl;
    system("pause");
    return 0;
}

参考:
http://blog.csdn.net/fengzhanghao23/article/details/47380793

http://zhidao.baidu.com/link?url=cJqhbNBAvGkkOGNLp4I-himqHpRxBSO1MKlV4RREKsNN16vqEi2FoiAXgoxIPqwHgr-L4nq2nG–y5UdzNIHj_

http://wenku.baidu.com/link?url=b1UwIq0hQab3vVAnw0HgajGv6XBTdOovtlS1uFDnH1ZU5iyU8yvM7A3z10Q1Cz1Kjj3hzVFq4KL8-CYwpDFwFeP-j7zqAsyMBDsKV4BuPfa

http://blog.163.com/fuchang_he/blog/static/110775491200922410042537/

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于中缀表达式求值,一般需要借助栈来完成。具体的步骤如下: 1. 创建一个运算符栈和一个操作数栈。 2. 从左到右遍历中缀表达式的每一个元素。 - 如果当前元素是操作数,直接将其压入操作数栈。 - 如果当前元素是运算符,分为以下几种情况处理: - 如果运算符栈为空或者栈顶运算符是"(",则直接将该运算符压入运算符栈。 - 如果当前运算符的优先级大于栈顶运算符的优先级,将当前运算符压入运算符栈。 - 如果当前运算符的优先级小于或等于栈顶运算符的优先级,将栈顶运算符弹出,并将其与操作数栈栈顶的两个操作数进行计算,将计算结果压入操作数栈,并将当前运算符压入运算符栈。重复这一步骤直到当前运算符的优先级大于栈顶运算符的优先级。 - 如果当前运算符为")",则依次弹出运算符栈的栈顶元素,直到栈顶元素为"("。将弹出的运算符与操作数栈栈顶的两个操作数进行计算,将计算结果压入操作数栈。 3. 遍历完中缀表达式后,将运算符栈中的剩余运算符依次弹出,并对操作数栈栈顶的两个操作数进行计算,将计算结果压入操作数栈。 4. 遍历完后,将操作数栈中的唯一元素即为中缀表达式的求值结果。 需要注意的是,对于乘法和除法这样的高优先级运算符,要先进行计算再进行压栈操作,而对于加法和减法这样的低优先级运算符,只有在栈顶运算符优先级小于当前运算符时才进行计算。 这就是中缀表达式求值的基本步骤。通过按照以上步骤运算,可以得到中缀表达式c的求值结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值