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