#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”值,但操作无效。
答案 0 :(得分:2)
你可能意味着
switch(input[i])
代替
switch(operation.top())
答案 1 :(得分:1)
更新对代码更改的响应
operators
上的operands
操作的运算符digits
(0123456789)组成;因此,您需要阅读多个字符才能在number
上推送operand stack
operators
+ - / *取 2 operands
,因此对大小<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标志,否则会导致段错误)
只是为了好玩:
#include <iostream>
#include <stack>
#include <vector>
#include <limits>
#include <string>
#include <stdexcept>
#include <iterator>
#include <fstream>
using namespace std;
template <class T>
static void dumpstack(std::stack<T> s/*byval!*/)
{
std::vector<T> vec;
while (!s.empty())
{
vec.push_back(s.top());
s.pop();
}
std::copy(vec.rbegin(), vec.rend(), std::ostream_iterator<int>(std::cout, " "));
}
class calc
{
private:
std::stack<int> _stack;
int _accum;
bool _pending;
void store(/*store accumulator if pending*/)
{
if (_pending)
{
_stack.push(_accum);
_pending = false;
_accum = 0;
}
}
public:
calc() : _accum(0), _pending(false)
{
}
void handle(char ch)
{
switch (ch)
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
_pending = true;
_accum *= 10;
_accum += ch-'0';
break;
case '+': case '-': case '/': case '*':
{
store();
if (_stack.size()<2)
throw std::runtime_error("stack underflow");
int op2 = _stack.top(); _stack.pop();
int op1 = _stack.top(); _stack.pop();
switch (ch)
{
case '+': _stack.push(op1 + op2); break;
case '-': _stack.push(op1 - op2); break;
case '/': _stack.push(op1 / op2); break;
case '*': _stack.push(op1 * op2); break;
}
// feedback to console:
std::cout << std::endl << "(evaluated: " << op1 << " " << ch << " " << op2 << " == " << _stack.top() << ")" << std::endl;
dump();
}
break;
default:
store(); // todo: notify of ignored characters in input?
}
}
void dump() const
{
dumpstack(_stack);
}
};
int main()
{
cout << "Enter postfix expressions: " << endl;
calc instance;
try
{
while (std::cin.good())
{
char ch = std::cin.get();
instance.handle(ch);
}
std::cout << "Final result: ";
instance.dump();
return 0;
} catch(const std::exception& e)
{
std::cerr << "E: " << e.what() << std::endl;
return 255;
}
}
测试输出:(请注意,您可以在按回车后继续使用剩余的,部分评估的堆栈)
Enter postfix expressions:
1 2 3 +4 * - / 1333 *
(evaluated: 2 + 3 == 5)
1 5
(evaluated: 5 * 4 == 20)
1 20
(evaluated: 1 - 20 == -19)
-19 E: stack underflow
答案 2 :(得分:0)
代码有很多问题,从解析输入表达式开始。实际崩溃很可能是因为如果您输入类似"12+"
的内容,则会将'1'
和'2'
推入堆栈(注意:字符1和2,而不是值1和2 !!!)然后尝试提取两个操作数和一个你从未插入堆栈的操作符。
在解析输入时,您正在逐字符地阅读,并且仅使用第一个数字,解析无法处理空格或任何其他分隔符...尝试将问题分解为两个:解析和处理。解析的问题可以通过不使用读取的实际值来解决,而只是打印它们(或以某种形式存储然后打印整个读取表达式),并且可以是第一步。确保解析器能够以健壮的方式处理诸如“1 2 +”,“10 20 +”,“1 2 +”,“1 2 +”(注意空格的不同位置)等常用表达式。并且优雅地解析像“+”,“1 +”,“1 2 ++”这样的表达式...你永远不会相信用户输入,他们会犯错误,不应该让你的程序瘫痪。< / p>
一旦确定能够解析输入,请从实际算法开始。使其对以前无法解决的无效用户输入具有鲁棒性,例如“10 0 /”并进行实际处理。
学习使用调试器,它将帮助您了解事情何时向南发生的原因。调试器只需不到一秒的时间来指出上面代码中的特定问题,它不会告诉你它为什么会死,但它会告诉你它是如何死的以及程序的状态是什么。如果我的预感是正确的,那么它将指向你operation.top()
指令作为罪魁祸首,你将能够看到你试图提取比插入更多的元素。逐步执行程序的一部分以了解它实际执行的操作,并且您会注意到当您读取“12+”时,实际上是将两个看似无关的整数存储到堆栈中('1'
的ASCII值和'2'
......