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’操作退出程序,程序執行完畢。