将中缀表达式转化为逆波兰式(c++实现)

<pre name="code" class="cpp">/*************************************************************************
	> File Name: ReversePolish.cpp
	> Author: Shaojie Kang
	> Mail: kangshaojie@ict.ac.cn 
	> Created Time: 2015年09月16日 星期三 11时17分04秒 
    > Problem:
        将中缀表达式转化为逆波兰式,并计算
 ************************************************************************/

#include<iostream>
#include<string>
#include<stack>
#include<cctype>
#include<map>
#include<cstdlib>
#include<vector>
using namespace std;

/* 优先级定义 */
map<string, int> precedence;

/* transfer function */
vector<string> Transfer(string &str)
{
    vector<string> result;
    stack<string> operators;
    if(str.empty()) return result;
    str.insert(0, 1, '(');
    str.push_back(')');
    int size = str.size();

    for(int i = 0; i < size; ++i)
    {
        // 忽略空格 
        if(str[i] == ' ') continue;
        // 提取数字
        if(isdigit(str[i])) 
        {
            string temp;
            while(i < size && isdigit(str[i]))
            {
                temp += str[i];
                ++i;
            }
            result.push_back(temp);
            --i;
            continue;
        }
        // 将(压入栈
        if(str[i] == '(') 
            operators.push(string(1, str[i]));
        // 遇到右括号是,左括号之前的操作符都要出栈
        else if(str[i] == ')')
        {
            while(operators.top() != "(")
            {
                result.push_back(operators.top());
                operators.pop();
            }
            operators.pop(); // 左括号出栈
        }
        else if(operators.empty() || precedence[string(1, str[i])] > precedence[operators.top()])    
            operators.push(string(1, str[i]));
        else // 当前操作符的优先级大于栈顶操作符的优先级  
        {
            // 优先级大于当前操作符的操作符都要出栈
            while(!operators.empty()) 
            {
                string op = operators.top();
                if(precedence[op] >= precedence[string(1, str[i])])
                {
                    result.push_back(op);
                    operators.pop();
                }
                else break;
            }
            operators.push(string(1, str[i])); // 将当前操作符号入栈
        }    
    }
    return result;
}

// 计算逆波兰式
int Calculate(string &operations)
{
    vector<string> result = Transfer(operations);
    stack<int> nums;
   
    for(int i = 0; i < result.size(); ++i)
    {
        if(isdigit(result[i][0]))
            nums.push(atoi(result[i].c_str()));
        else 
        {
            int num2 = nums.top();
            nums.pop();
            int num1 = nums.top();
            nums.pop();
            if(result[i] == "+") 
                nums.push(num1 + num2);
            else if(result[i] == "-")
                nums.push(num1 - num2);
            else if(result[i] == "*")
                nums.push(num1 * num2);
            else nums.push(num1 / num2);
        }
    }
    return nums.top();
}

void print(const vector<string> nums)
{
    for(int i = 0; i < nums.size(); ++i)
        cout<<nums[i]<<" ";
    cout<<endl;
}

int main()
{
    precedence["("] = -1;
    precedence["+"] = precedence["-"] = 0;
    precedence["*"] = precedence["/"] = 1;
    string str("5/4+2*(3+2)*10");

    cout<<Calculate(str)<<endl;

    return 0;
}



                
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值