1. 程式人生 > >表示式翻譯

表示式翻譯

一,對錶達式翻譯的認識:

                          由中綴變字尾,即由標註的算術表示式變為計算機易識別的式子,並輸出結果.例:中綴為:  9+(3-1)*3+10/2   變為字尾:  9 3 1 – 3 * + 10 2 + /  計算結果為: 20

 二 ,轉換的主要思想:

第一步:遇到數字9在後綴表示式中直接輸出,接著是符號”+”入棧 ,



 第二步:第三個字元是“(”,依然是符號,這個時候將此符號入棧,接著是數字3,直接輸出,然後是符號“-”,這個時候符號仍然入棧



第三步:接下來是數字1輸出,緊跟著是“)”,此時,我們需要匹配棧裡的“(”,然後再匹配前將棧頂資料依次出棧:



 第四步:緊接著是符號“*”,直接入棧:



 第五步:遇到數字3,直接輸出,之後是符號“+”,此時棧頂元素是符號“*

”,按照先乘除後加減原理,此時棧頂的乘號優先順序比即將入棧的加號要大,所以出棧。而棧中的第二個元素是加號,按照先到先後的原則,這個時候“+”也要出棧。



 第六步:緊接著是數字10,直接輸出,最後是符號“/”,進棧:



 第七步:最後一個數字5,這個時候直接輸出5,但是棧裡仍然有資料,此時可以將棧中符號依次出棧。

三,對字尾表示式的計算:

1. 初始化一個空。此桟用來對要運算的數字進出使用。

2. 字尾表示式中前三個都是數字,所以931進棧。



3. 

接下來是減號“-”,所以將棧中的1出棧作為減數,3出棧作為被減數,並運算3-1得到2,再將2進棧。

4. 接著是數字3進棧。



5. 後面是乘法“*”,也就意味著棧中32出棧,23相乘,得到6,並將6進棧。

6. 下面是加法“+”,所以找中69出找,96相加,得到15,將15進棧。



7. 接著是102兩數字進棧。

8. 接下來是符號因此,棧頂的210出棧,102相除,得到5,將5進棧。



9. 最後一個是符號“+”,所以155出找並相加,得到20,將20進棧。

10. 結果是20出棧,棧變為空。



,核心程式碼

(1)     由字首變字尾:

char* GetBack()//獲取字尾表示式的函式

{

    char* middle = new char[30];

    char* back = new char[30];

    char* backend = back;

    InPut(middle);

    stack s;

    s.push('#');

    while (*middle)

    {

        if (Number(*middle) || *middle =='.')//如果是數字或者小數的話,直接輸出

        {

            *back = *middle;

            back++, middle++;

        }

        else

        {

            if (Number(*(back - 1)))//只有他的上一個時數字的話,才繼續給空格

                                    //否則遇到多個操作符,則輸出域會存在多個空格

            {

                AddSpace(back);

            }

            if (*middle == ')')//如果右括號的話,輸出所有操作符直到遇到左括號,並拋棄相對應的一堆括號

            {

                while (s.top() != '(')

                {

                    *back = s.top();

                    s.pop();

                    back++; middle++;

                    AddSpace(back);

                }

                s.pop();//拋棄左括號

            }

            else if (*middle == '(')//遇到左括號,則進入棧

            {

                s.push(*middle); middle++;

            }

            else if (GetPriority(*middle) >GetPriority(s.top()))//如果棧內的操作符優先順序高於棧外的優先順序,則入棧

            {

                s.push(*middle); middle++;

            }

            else if (GetPriority(*middle) <=GetPriority(s.top()))

                                            //如果棧內的操作符優先順序低於或等於棧外的優先順序,輸出棧內的符號,併入棧棧外的符號

            {

                *back = s.top();

                s.pop();

                s.push(*middle);

                back++; middle++;

                AddSpace(back);

            }

        }

    }

    while (s.top() != '#')//中綴表示式遍歷完成,但是=棧中還有符號存在,一一出棧輸出

    {

        AddSpace(back);

        *back = s.top();

        s.pop(); back++;

    }

    *back = '\0';

    cout << "字尾表示式為: " << backend << endl;

    return backend;

}

(2)    字尾表示式的計算:

double CountBack(char*back)

{

    stack s;

    while (*back)

    {

        if (Number(*back))//遇到數字

        {

            s.push(GetNumber(back));//將正確的數字入棧

        }

        else if (*back == ' ')

        {

            back++;//遇到空格跳過

        }

        else

        {

            double a = s.top();

            s.pop();

            double b = s.top();

            s.pop();

            s.push(Cauculate(*back, b, a));//遇到符號時,取棧頂的第二個數和第一個數求解,併入棧

            back++;

        }

    }

    while (s.size() >= 2)//最終棧記憶體在的數大於2時,繼續計算,直到只剩下一個數

    {

        double a = s.top();

        s.pop();

        double b = s.top();

        s.pop();

        s.push(Cauculate(*back, b, a));

    }

    //返回這個數字,既是最終結果

    return s.top();

}