OpenJudge题目解析-中缀表达式的值

题目描述

中缀表达式的值http://stepbystep.openjudge.cn/stackqueue/10/

思路要点

  1. 输入字符串,而后解析得到操作符和操作数(用字符串数组存储)
  2. 利用操作符栈和操作数栈对表达式进行求解

代码

#include <iostream>
#include <string>
#include <vector>
#include <assert.h>
#include <stack>
#include <cstdlib>
using namespace std;

//把表达式分解为运算符和操作符的数组
void parseExprStr(string expr, vector<string>& expVct);
//打印运算符和操作符的数组
void printExpVct(vector<string>& expVct);
//求解表达式结果
int getResult(vector<string>& expVct);


int main()
{
    int expNum;
    cin >> expNum;
    string line;
    getline(cin, line);
    for (int i = 0; i < expNum; i++)
    {
        getline(cin, line);
        vector<string> expVct;
        parseExprStr(line, expVct);
        //printExpVct(expVct);
        cout << getResult(expVct) << endl;
    }
}

void parseExprStr(string expr, vector<string>& expVct)
{
    assert(!expr.empty());
    int i = 0;
    while (i < expr.length())
    {
        if (isdigit(expr[i]))
        {
            string digitStr(1, expr[i]);
            i++;
            while (i < expr.length() && isdigit(expr[i]))
            {
                digitStr += expr[i];
                i++;
            }
            expVct.push_back(digitStr);
        }
        else
        {
            expVct.push_back(string(1, expr[i]));
            i++;
        }
    }
}

void printExpVct(vector<string>& expVct)
{
    cout << "The expression is: ";
    for (int i = 0; i < expVct.size(); i++)
        cout << expVct[i] << " ";
    cout << endl;
}

void handleCalculation(char opt, stack<int> &operands)
{
    assert(operands.size() >= 2);
    int right = operands.top();
    operands.pop();
    int left = operands.top();
    operands.pop(); 
    switch(opt)
    {
    case '+':
        operands.push(left + right);
        break;
    case '-':
        operands.push(left - right);
        break;
    case '*':
        operands.push(left * right);
        break;
    case '/':
        operands.push(left / right);
        break;
    }
}

int getLevel(char opt)
{
    switch(opt)
    {
    case '(':
        return 1;
    case '+':
    case '-':
        return 2;
    case '*':
    case '/':
        return 3;
    }
}

//leftOp优先级高于或等于rightOp,则返回true,否则返回false
bool higherThan(char leftOpt, char rightOpt)
{
    return getLevel(leftOpt) >= getLevel(rightOpt);
}

void handlePriorOperators(char opt, stack<int> &operands, stack<char>& opts)
{
    while (!opts.empty() && higherThan(opts.top(), opt) )
    {
        handleCalculation(opts.top(), operands);
        opts.pop();
    }
    return;
}

void handleOperator(char opt,stack<int> &operands, stack<char>& opts)
{
    switch(opt)
    {
    case '(':
        opts.push(opt);
        break;
    case ')':
        while(!opts.empty() && opts.top() != '(')
        {
            handleCalculation(opts.top(), operands);
            opts.pop();
        }
        if (!opts.empty()) 
            opts.pop();  //'('
        break;
    case '+':
        handlePriorOperators('+', operands, opts);
        opts.push('+');
        break;
    case '-':
        handlePriorOperators('+', operands, opts);
        opts.push('-');
        break;
    case '*':
        handlePriorOperators('*', operands, opts);
        opts.push('*');
        break;
    case '/':
        handlePriorOperators('/', operands, opts);
        opts.push('/');
        break;
    }
}

int getResult(vector<string>& expVct)
{
    stack<int> operands;  //操作数栈
    stack<char> opts;       //操作符栈
    for (int i = 0; i < expVct.size(); i++)
    {
        string op = expVct[i];
        if (isdigit(op[0]))
        {
            operands.push(atoi(op.c_str()));
        }
        else
        {
            handleOperator(op[0], operands, opts);
        }
    }
    while(!opts.empty())
    {
        handleCalculation(opts.top(), operands);
        opts.pop();
    }
    assert(operands.size() == 1);
    return operands.top();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值