雙端隊列棧的應用 逆波蘭表達式求值

1.目的

基於雙端隊列的頭插、頭刪操作,完成棧的應用:逆波蘭表達式求值,測試和調試程序。
遇到操作數,則入棧;
遇到二元運算符,則連續從棧中彈出兩個操作數,先彈出的做第二操作數,後彈出的做
第一操作數,與該二元運算符作用後,將得到的結果再存入棧中;
遇到一元運算符,則從棧中彈出一個操作數,與該一元運算符作用後,將得到的結果再
存入棧中;
按照上面的規則,掃描後綴表達式(由鍵盤讀到):2、3 是操作數,依次入棧;之後
碰到加號“+”這個二元運算符,則 3、2 依次出棧,2 爲第一操作數,3 爲第二操作數,
執行加法,和爲 5,入棧;加號後面的 6 是操作數入棧;之後的乘號“*”是二元運算
符,則 6、5 依次出棧,5 爲第一操作數,6 爲第二操作數,執行乘法,積爲 30,入
棧;之後可以使用打印棧頂元素的操作(該次實驗中使用命令“p”),將最後結果在
屏幕上輸出。
程序要求從鍵盤接收字符串,然後按照上面的思想,求解該字符串對應的逆波蘭式表達
式的值。

2.程序
頭文件引用dlist.cpp(見上條博客 :用C++語言實現雙端隊列)

#include<iostream>
#include"dlist.cpp"

using namespace std;

bool do_command(Dlist<int> &mylist,char *n)  //根據輸入字符執行相應操作
{
    int *p = NULL;
    int *q = NULL;
    Dlist<int> temp;
    switch (*n) {
    case '+': //'+'表示取出棧頂兩個數據相加
        p = mylist.removeFront(); //取出原表中的第一個元素
        q = mylist.removeFront(); //取出原表中的第二個元素
        if(NULL != q) //判斷表中的數據是否夠兩個
        {
            *q = *p + *q; //將兩個數相加
            mylist.insertFront(q); //將結果插入表中
        }
        else{ //如果第二個指針是空,則原表中說明不夠兩個元素
            if(p != NULL) mylist.insertFront(p); //如果第一個元素被取出,則重新插回
            cout << "Not enough operands\n"; //輸出信息
        }
        return true;
    case '-': //'-'表示取出棧頂兩個數據相減
        p = mylist.removeFront();//取出原表中的第一個元素
        q = mylist.removeFront();//取出原表中的第二個元素
        if(NULL != q) //判斷表中的數據是否夠兩個
        {
            *q = *q - *p; //將兩個數相減
            mylist.insertFront(q);//將結果插入表中
        }
        else{//如果第二個指針是空,則原表中說明不夠兩個元素
            if(p != NULL) mylist.insertFront(p); //如果第一個元素被取出,則重新插回
            cout << "Not enough operands\n"; //輸出信息
        }
        return true;
    case '*': //'*'表示取出棧頂兩個數據相乘
        p = mylist.removeFront();
        q = mylist.removeFront();
        if(NULL != q)
        {
            *q = *q * *p;//將兩個數相乘
            mylist.insertFront(q);
        }
        else{
            if(p != NULL) mylist.insertFront(p);
            cout << "Not enough operands\n";
        }
        return true;
    case '/': //'/'表示取出棧頂兩個數據相除
        p = mylist.removeFront();
        q = mylist.removeFront();
        if(NULL != q)
        {
            if(0 == *p) //判斷除數是否爲0
            {
                cout << "Divide by zero\n";
                return true;
            }
            *q = *q / *p; //將兩個數相除
            mylist.insertFront(q);
        }
        else{
            if(p != NULL) mylist.insertFront(p);
            cout << "Not enough operands\n";
        }
        return true;
    case 'n'://'n'表示返回表頭元素的相反數
        p = mylist.removeFront(); //取出表頭元素
        if(NULL != p)
        {
            *p = *p * (-1); //取相反數
            mylist.insertFront(p); //將結果插回表中
        }
        else{//如果指針是空,則原表中沒有元素
            cout << "Not enough operands\n";
        }
        return true;
    case 'd': //'d'複製棧頂元素
        p = mylist.removeFront();//取出表頭元素
        if(NULL != p)
        {
            mylist.insertFront(p); //將這個元素插回
            mylist.insertFront(p); //將這個元素插回
        }
        else{//如果指針是空,則原表中沒有元素
            cout << "Not enough operands\n";
        }
        return true;
    case 'r': //'r'交換前兩個元素的順序
        p = mylist.removeFront(); //取出原表中的第一個元素
        q = mylist.removeFront(); //取出原表中的第二個元素
        if(NULL != q)
        {
            mylist.insertFront(p); //先插入原來的第二個元素
            mylist.insertFront(q); //再插入第一個元素
        }
        else{ //如果指針是空,則原表中沒有元素
            cout << "Not enough operands\n";
        }
        return true;
    case 'p': //'p'打印出表頭元素
        p = mylist.removeFront(); //取出原表中的第一個元素
        cout << *p << endl;
        if(NULL != p)
        {
            mylist.insertFront(p); //將表頭插回
        }
        else{ //如果指針是空,則原表中沒有元素
            cout << "Not enough operands\n";
        }
        return true;
    case 'a': //'a'打印出表中所有元素,原表數據不變
        temp = mylist; //先將表中元素賦給臨時表
        p = temp.removeFront();
        while(NULL != p) //遍歷,逐個打印臨時表中的元素
        {
            cout << *p;
            p = temp.removeFront();
        }
        cout << endl;
        return true;
    case 'c': //'c'清空表中所有元素
        p = mylist.removeFront();
        if(NULL != p) //遍歷,逐個刪除
        {
            p = mylist.removeFront();
        }
        return true;
    case 'q': //'q'表示結束程序
        return false; //返回false,表示程序結束
    default:
        cout << "Bad input" << endl; //如果沒有該指令則返回相應信息
        return true;
    }
}

int main()
{
    Dlist<int> mylist;
    int *nu = NULL;
    char *c = new char();
    char number = 0;
    bool t;

    while(cin >> number)
    {
        if((number >= '0') && (number <= '9')) //檢測輸入的是不是數字
        {
            nu = new int(number - '0'); //如果是數字就將它賦給指針nu
            mylist.insertFront(nu); //將nu插入表中
        }
        else{ //如果輸入的不是數字
            *c = number; //將字符賦給指針c
            t  = do_command(mylist,c); //調用運算函數
            if(!t) //檢測程序是否結束
            {
                break; //如果程序結束就退出
            }
        }
    }
    delete nu;
    delete c;
}

3.結果
在這裏插入圖片描述
結果解釋:

 這個程序是雙端隊列中棧的應用,開始執行的是(3+4)*2這個式子,結果是14存入
 表中,’p’打印出表頭元素14,正確。再執行‘+’,此時表中只有一個數,所以應返回
 操作數不夠的信息,正確。然後執行‘d’操作,將表頭元素賦值,再執行‘+’,此時結
 果應爲28,打印表頭元素爲28,正確,最後-2,結果應爲26,打印表頭元素爲26,
 正確。最後‘q’操作退出程序,程序執行完畢。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章