中缀表达式求值 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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值