更新对代码更改的响应
我可以确认您更改了代码,但不是很好。
- 该代码大多具有它已经存在的所有缺陷,并且还有一些缺陷。
- 您现在将操作数组合成一个字符串流有什么好处?
- 您现在打开 (operand1,operand2)...
- 两者都未初始化
- (operand1,operand2) 在这种情况下基本上是指 (operand2) (序列运算符)
- 您的分支标签是 ... 运算符 (+-/*)
- 您现在打印一个最终结果,它是输入中所有数字的串联(如果您在没有崩溃的情况下到达程序末尾)?
在以前的错误中,仍应修复
- 堆栈计算器的心智模型。
- 数字(整数)是操作数(所以 9、100、39829 是有效的操作数)
- +-/* 是运算符(对 进行
operators
操作operands
)
- 堆栈是操作数堆栈,而不是运算符堆栈(不必记住运算符,因为它们会立即计算)
digits
数字连续由 1 个或多个(0123456789) 组成;所以你需要阅读几个字符才能“推”number
上operand stack
operators
+-/* 取2 ,因此对 size<2 堆栈的operands
任何操作都是错误(您需要检查这一点,否则程序将在尝试访问不存在或包含垃圾的内存时崩溃)。
这应该足以让你开始。
我认为有两件事是积极的:
- 你程序编译。+1 为您实际使用那里的编译器:)
- 您将重复
operation.push(result)
从开关中取出,因此不再重复。+1 编码风格...
我希望你能从中看出代码不是很好(说得委婉些),我真的认为一些基本练习是有序的: 1. 编写一个简单的 for 循环,将数字 1 到 10 打印到控制台 1 . 编写一个简单的 while 循环来打印用户输入的单词 1. 使用一个简单的循环来打印 1 到 50 之间的所有数字,这些数字是 7 的倍数 1. 每当用户输入其中一个时,使用 switch 语句打印“yes”字母 a、b、k 或 z 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