将中缀表达式转换成后缀表达式并计算

1、将以字符串形式输入的中缀表达式转换成后缀表达式

  1. 初始化一个空栈用于存储操作符
  2. 对于中缀表达式从左向右遍历,每得到一个字符,进行判断
    a、如果是数字,则直接加入到后缀表达式中,同时判断下一个
    字符是也是数字,如果是,也加入到后缀表达式中,如此循
    环判断,将连续的数字字符一并识别存储。

    b、如果是左括号,则把左括号入操作符栈。

    c、如果是右括号,则从操作符栈中把符号出栈加入后缀表达
    式中,直到遇到左括号停止并将左括号出栈。

    d、如果是操作符,首先判断操作符栈是否为空,如果为空,直接
    入栈,如果为左操作符,也直接入栈。如果非空,将该操作符
    与操作符栈的栈顶元素进行优先级比较,若当前操作符优先级
    大于栈顶优先级,那么当前操作符入栈,否则,栈顶操作符
    出栈加入到后缀表达式中(此处当前操作符不需要入栈),重复
    d步骤,直到当前操作符入栈(也就是说要保证栈顶操作符优
    先级最高)。

  3. 当中缀表达式搜索完毕后,检查操作符栈是否为空,如果非空,
    那么将其中的操作符添加到后缀表达式中。
    (同时注意,在转换的时候,每添加一个数字串、操作符到后缀表达式中的时候,在前面先添加一个空格,使得连续存储的数字不会连在一起,方便后面的后缀表达式计算)

2、计算后缀表达式

  1. 定义一个存储操作数的操作数栈。
  2. 从左向右遍历后缀表达式
    a、如果是空格,则跳过
    b、如果是数字,将其转换为整型,循环判断下一个字符是否为
    数字,转换成相应的多位整型数字形式,并将该整型数如操
    作数栈。
    c、如果是操作符,则从操作数栈中把栈顶的两个操作数出栈,
    判断操作符类型,并进行相应计算,然后将计算得到的结果
    重新入栈。
  3. 最后将操作数栈中的栈顶元素作为最终结果输出。
#include <iostream>
#include <Stack>
#include <string>
#include <cctype>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <cstring>
using namespace std;

string inTopostExp(string exp);    //
int prior(char c); //judge the priority of the operator
int computepostExp(string postExp);
int Auxcal(int a,int b,char ch);

int main()
{
    string inexp,posexp;
    for(;;)
    {
        cout<<"input a infix expression:(input exit to quit)";
        getline(cin,inexp);
        if(inexp=="exit")
        break; 
        posexp=inTopostExp(inexp); 
        cout<<"the reference postfix expression is:"<<posexp<<endl;
        cout<<"the compute result is:"<<computepostExp(posexp)<<endl;
    }
    return 1;
}

int Auxcal(int a,int b,char ch)
{
    switch(ch)
    {
        case'+':return a+b;
        case'-':return a-b;
        case'*':return a*b;
        case'/':return a/b;
    }
}

int computepostExp(string postExp)
{
    char curch;
    int num1,num2;
    stack<int> numStack; 
    for(int i=0;i<postExp.length();i++)
    {
        curch=postExp[i];
        if(postExp[i]==32)
        {
            continue;
        }
        else if(postExp[i]<'9'&&postExp[i]>'0')
        {
            int tmpnum=int(postExp[i])-'0';
            while(postExp[i+1]<'9'&& postExp[i+1]>'0')
            {
                tmpnum=tmpnum*10+int(postExp[i+1])-'0';
                i++;
            }
            numStack.push(tmpnum);
        }
        else
        {
            num2=numStack.top();
            numStack.pop();
            num1=numStack.top();
            numStack.pop();
            numStack.push(Auxcal(num1,num2,curch));
        }
    }
    return numStack.top();
}

int prior(char c)
{
    switch(c)
    {
        case'+':case'-':return 1;
        case'*':case'/':case'%':return 2;
    }
}

string inTopostExp(string exp)
{
    string postExp;
    char curtoken,toptoken;
    stack<char> opStack;
    for(int i=0;i<exp.length();i++)
    {
        curtoken=exp[i];
        if(isalnum(curtoken))
        {
            postExp.append(1,' ');
            postExp.append(1,curtoken);
            for(;isalnum(exp[i+1]);i++)
            {
                postExp.append(1,exp[i+1]);
            }
            continue;
        }
        else
        {
            switch(curtoken)
            {
                case '(':
                    opStack.push(curtoken);
                    break; 
                case')':
                    while(opStack.top()!='(')
                    {
                        toptoken=opStack.top();
                        postExp.append(1,toptoken);
                        opStack.pop();
                    }
                    opStack.pop();
                    break;
                case'+':case'-':case'*':case'/':case'%':
                    for(;;)
                    {
                        if(opStack.empty())
                        {
                            opStack.push(curtoken);
                            break;
                        }
                        else if(opStack.top()=='(')
                        {
                            opStack.push(curtoken);
                            break;
                        }
                        else if(prior(opStack.top())<prior(curtoken))
                        {
                            opStack.push(curtoken);
                            break;
                        }
                        else   
//若栈顶符号优先级大于当前符号优先级,则该符号出栈,但此时当前符号不入栈,因为还需继续判断下一个优先级,也就是说这一步只是将操作符栈栈顶的符号出栈进入后缀表达式中。 
                        {
                            toptoken=opStack.top();
                            postExp.append(1,' ');
                            postExp.append(1,toptoken);
                            opStack.pop();
                        }
                    }
                    break;
            }
        }
    }
    //最后一个字符如果是数字,那么栈内还有没出栈的符号
    while(!opStack.empty())
    {
        toptoken=opStack.top();
        postExp.append(1,' ');
        postExp.append(1,toptoken);
        opStack.pop();
    } 
    return postExp;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

弹指间LLL

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

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

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

打赏作者

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

抵扣说明:

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

余额充值