在 C++ 中使用堆栈评估后缀
#include <iostream>
#include <sstream>
#include <stack>
#include <limits>
#include <string>
using namespace std;
int main()
{
string input;
cout << "Enter a postfix expression: " << endl;
getline(cin, input);
int operand1, operand2, result,number;
stack<char>operation;
stringstream temp;
int i=0;
while (i < input.length())
{
if (isdigit(input[i]))
{
operation.push(input[i]);
}
else
{
operand2 = operation.top();
temp << operation.top();
operation.pop();
operand1 = operation.top();
temp << operation.top();
operation.pop();
switch(operand1,operand2)
{
case '+': result=operand1 + operand2;
break;
case '-': result=operand1 - operand2;
break;
case '*': result=operand1 * operand2;
break;
case '/': result=operand1 / operand2;
break;
}
operation.push(result);
}
i++;
}
cout << "The result is: "<<temp.str()<<endl;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return 0;
}
我更改了代码并设法获取“pop”值,但操作不起作用。
#include <iostream>
#include <sstream>
#include <stack>
#include <limits>
#include <string>
using namespace std;
int main()
{
string input;
cout << "Enter a postfix expression: " << endl;
getline(cin, input);
int operand1, operand2, result,number;
stack<char>operation;
stringstream temp;
int i=0;
while (i < input.length())
{
if (isdigit(input[i]))
{
operation.push(input[i]);
}
else
{
operand2 = operation.top();
temp << operation.top();
operation.pop();
operand1 = operation.top();
temp << operation.top();
operation.pop();
switch(operand1,operand2)
{
case '+': result=operand1 + operand2;
break;
case '-': result=operand1 - operand2;
break;
case '*': result=operand1 * operand2;
break;
case '/': result=operand1 / operand2;
break;
}
operation.push(result);
}
i++;
}
cout << "The result is: "<<temp.str()<<endl;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return 0;
}
I've changed the code and managed to obtain the "pop" value, but the operation didn't work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你可能的意思
是
You probably meant
instead
更新对代码更改的响应
我可以确认您更改了代码,但不是以一种好的方式。
在以前错误的事情中,仍然应该修复
运算符
对操作数
进行操作)数字
(0123456789) 组成;因此,您需要先读取几个字符,然后才能将数字
“压入”操作数堆栈
运算符
+-/* 采用2操作数
,因此对大小<2的堆栈上的任何操作都是错误的(您需要检查这一点,否则程序会在尝试访问不存在或包含垃圾的内存时崩溃)。这应该足以让您开始。
我认为有两件事是积极的:
operation.push(result)
从开关中取出,因此它不再重复。编码风格+1...我希望您可以从中了解到代码不是很好(温和地说),我真的认为一些基本练习是有序的:
1. 编写一个简单的 for 循环,将数字 1 到 10 打印到控制台
1. 编写一个简单的 while 循环来打印用户输入的单词
1. 使用一个简单的循环打印 1 到 50 之间所有 7 的倍数的数字
1. 每当用户输入字母 a、b、k 或 z 之一时,使用 switch 语句打印“yes”
2. 创建一个简单的循环,仅打印相同字符后面的每个字符的输入字符(因此“abccdefgghijkllmabcdd”将变为“cgld”)
1. 使用相同的循环,但这次打印紧随相同单词的每个单词(因此“不,不,你不应该弹出,弹出,而是推,弹出”变成“不弹出”)
这应该会让您感受到事物的实际运作方式,而无需猜测或“神奇因素”。
哦,别忘了,我在下面为您实现了整个过程。我不建议你盲目地复制它(这对你的老师来说是相当明显的:))但是如果你想知道我上面所有的话是什么意思,你可以看一眼:)
您正在推送松散的数字,而不是已解析的数字
在第 31 行中,您弹出一个可能为空的堆栈(导致段错误,除非您使用调试模式 STL编译器上的标志)
只是为了好玩:
测试输出:(请注意,您可以继续剩余的、部分评估的、按回车后堆栈)
Update response to code changes
I can confirm you changed the code, but not in a good way.
Among the things that were wrong before, and should still be fixed
operators
operate on theoperands
)digits
(0123456789) in a row; so you'd need to read several characters before you can 'push' anumber
on theoperand stack
operators
+-/* take 2operands
, so any operation on a stack of size<2 is an error (you need to check that or the program will crash while trying to access memory that doesn't exist or contains rubbish).That should be enough to get you started.
Two things I do think are positive:
operation.push(result)
out of the switch so it isn't duplicated anymore. +1 for coding style ...I hope you can gather from this that the code isn't very good (to put it mildly), and I really think some basic exercises are in order:
1. write a simple for loop that prints numbers 1 to 10 to the console
1. write a simple while loop that prints words entered by the user
1. use a simple loop to print all numbers between 1 and 50 that are multiples of 7
1. use a switch statement to print "yes" whenever the user enters one of the letters a, b, k, or z
2. make a simple loop that only prints the input character for every character that follows the identical (so 'abccdefgghijkllmabcdd' would become 'cgld')
1. use the same loop but this time print every word that immediately follows the identical word (so "no, no, you should not pop, pop, but push, pop" becomes "no pop")
That should give you a feel for how things really work, without the guesswork or the 'magic factor'.
Oh, and don't forget, I implemented the whole thing for you below. I don't suggest you blindly copy it (it will be rather obvious to your teacher :)) but it is there for you to take a peek if you want to know, what I mean with all my words above :)
You are pushing loose digits, not parsed numbers
In line 31 you pop a possibly empty stack (resulting in segfault unless you use the debug-mode STL flags on your compiler)
Just for fun:
Test output: (note that you can continue with the remaining, partially evaluted, stack after pressing carriage return)
从输入表达式的解析开始,代码有很多问题。实际崩溃很可能是由于以下事实:如果您输入类似
"12+"
的内容,您将推送'1'
和'2'
到堆栈中(注意:字符 1 和 2,而不是值 1 和 2!!!),然后尝试提取两个操作数和一个从未插入到堆栈中的运算符。在解析输入时,您正在逐个字符地读取,并且仅使用第一个数字,解析无法处理空格或任何其他分隔符...尝试将问题一分为二:解析和处理。解析问题可以通过不使用实际读取的值,而只是打印它们(或以某种形式存储,然后打印整个读取的表达式)来解决,这可以是第一步。确保解析器能够以稳健的方式处理常见表达式,如“1 2 +”、“10 20 +”、“1 2+”、“1 2 +”(注意空格的不同位置)。并且它无法优雅地解析“+”、“1 +”、“1 2 ++”等表达式...您永远不能信任用户输入,他们会犯错误,但这不应该使您的程序崩溃。
一旦确定能够解析输入,就开始实际的算法。使其对您之前可能无法处理的无效用户输入(例如“10 0 /”)具有鲁棒性,并进行实际处理。
学习使用调试器,它将帮助您了解事情出现问题时的原因是什么。调试器将花费不到一秒钟的时间来指出上面代码中的特定问题,它不会告诉您它为什么死掉,但它会向您显示它是如何死掉的以及程序的状态。如果我的预感是正确的,那么它会将您指出
operation.top()
指令作为罪魁祸首,并且您将能够看到您试图提取的元素多于插入的元素。逐步执行程序的一部分以了解它实际上在做什么,您会注意到,当您读取“12+”时,您实际上将两个看似无关的整数存储到堆栈中('1的 ASCII 值) '
和'2'
...There are many things wrong with the code, starting with parsing of the input expression. The actual crash is most probably due to the fact that if you input something like
"12+"
you will push'1'
and'2'
into the stack (note: characters 1 and 2, not values 1 and 2!!!) and then try to extract two operands and an operator that you never inserted into the stack.On parsing the input, you are reading character by character, and only using the first digit, the parsing is not able to handle spaces or any other separator... Try to break the problem in two: parsing and processing. The problem of parsing can be tackled by not using the actual values read, but just printing them (or storing in some form and then printing the whole read expression), and can be a first step. Ensure that the parser is able to deal with common expressions like "1 2 +", "10 20 +", "1 2+", " 1 2 + " (note the different positions of spaces) in a robust way. And that it fails gracefully to parse expressions like " +", "1 +", "1 2 ++"... You can never trust user input, they will make mistakes and that should not bring your program to its knees.
Once you are sure that you are able to parse the input, start on the actual algorithm. Make it robust against invalid user inputs that you might have not been able to tackle before, like "10 0 /" and do the actual processing.
Learn to use the debugger, it will help you understand when things go south what are the reasons. The debugger would take less than one second to point at the specific problem in your code above, it will not tell you why it died, but it will show you how it died and what the state of the program was there. If my hunch is correct, then it will point you at the
operation.top()
instruction as the culprit, and you will be able to see that you were trying to extract more elements than were inserted. Execute a part of your program step by step to understand what it is actually doing, and you will notice that when you read "12+" you are actually storing two seemingly unrelated integers into the stack (the ASCII values of'1'
and'2'
...