將中綴表達式轉換成後綴表達式並計算

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章