[英]Postfix calculation with stack class, C++
我正在尝试使用自定义堆栈类来计算后缀形式的方程。 出于某种原因,程序不断崩溃。
这是堆栈头文件
#ifndef aStack_h
#define aStack_h
#include <string>
#include <iostream>
using std::string; using std::cout;
class aStack
{
private:
int top, size;
int *stack;
public:
aStack(int s)
{
size = s;
top = -1;
stack = new int [s];
}
~aStack()
{
delete [] stack;
}
void reset();
void push(int);
void pop();
int getTop();
void getSize()
{
std::cout << size;
}
};
#endif
类实现文件:
#include "aStack.h"
#include <iostream>
using namespace std;
void aStack::pop()
{
if (top == -1)
{ cout << "Stack is already empty.\n";}
stack[--top];
}
void aStack::push(int v)
{
if (top == size)
{ cout << "Stack is full.\n";}
stack[top++] = v;
}
void aStack::reset()
{
top = -1;
}
int aStack::getTop()
{
return top;
}
这是主程序
#include <iostream>
#include "aStack.h"
#include <string>
using namespace std;
int main()
{
string equation {"35+1*"};
int op, count = 0, *oparray, result;
aStack stack(equation.length());
for (int i = 0; i < equation.length(); i++)
{
if (isdigit(equation[i]))
{
stack.push(equation[i]);
count++;
}
else
{
oparray = new int [count];
for (int o = 0; o < count; o++)
{
oparray[o] = stack.getTop();
stack.pop();
}
switch(equation[i])
{
case '+':
for (int i =0; i < count; i++)
{
op += oparray[i];
count--;
}
stack.push(op);
break;
case '-':
for (int i =0; i < count; i++)
{
op-=oparray[i];
count--;
}
stack.push(op);
break;
case '*':
for (int i =0; i < count; i++)
{
op*=oparray[i];
count--;
}
stack.push(op);
break;
case '/':
for (int i =0; i < count; i++)
{
op/=oparray[i];
count--;
}
stack.push(op);
break;
}
delete [] oparray;
}
}
result = stack.getTop();
cout << result;
}
我知道我不应该使用“using namespace std;”,我很着急。 我怀疑这会是我问题的原因。 任何帮助是极大的赞赏。
您的堆栈类在评论中已经指出了其他问题。 修复了这些问题后,主程序中只剩下一些错误。
我在您的数组中使用了std::unique_ptr<>
而不是原始指针并禁用了移动语义,因此它既不可复制(因为unique_ptr
)也不可移动。
如果您尝试越界访问堆栈,我还添加了抛出异常。
#include <cctype>
#include <cstddef>
#include <exception>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <utility>
template<typename T>
class aStack {
public:
using value_type = T;
explicit aStack(size_t c) :
cap(c), stored(0), stack(std::make_unique<value_type[]>(cap)) {}
aStack(aStack&&) = delete; // moving disabled
void reset() noexcept { stored = 0; }
void push(const value_type& v) {
if(stored == cap) throw std::runtime_error("stack is full");
stack[stored++] = v;
}
void push(value_type&& v) {
if(stored == cap) throw std::runtime_error("stack is full");
stack[stored++] = std::move(v);
}
value_type& pop() {
if(stored == 0) throw std::runtime_error("stack is empty");
return stack[--stored];
}
[[nodiscard]] const value_type& top() const {
if(stored == 0) throw std::runtime_error("stack is empty");
return stack[stored - 1];
}
[[nodiscard]] value_type& top() {
if(stored == 0) throw std::runtime_error("stack is empty");
return stack[stored - 1];
}
[[nodiscard]] size_t capability() const noexcept { return cap; }
[[nodiscard]] size_t size() const noexcept { return stored; }
private:
size_t cap, stored;
std::unique_ptr<value_type[]> stack;
};
说到主程序,主要的问题是你忘记把每个数字的ASCII值转换成整数。 另一个问题是op
计算。 您保留了上次迭代的值,而不是从堆栈中获取新值。 还有一个额外的内存分配是不必要的,所以我删除了它。 你也有阴影变量,它不会导致任何错误,但让阅读代码变得非常困难。
int main(int argc, char* argv[]) {
if(argc < 2) {
std::cout << "USAGE: " << argv[0] << " <equation>\n";
return 1;
}
std::string equation(argv[1]);
try {
int op, result;
aStack<int> stack(equation.length());
for(size_t ei = 0; ei < equation.length(); ++ei) {
if(std::isdigit(equation[ei])) {
stack.push(equation[ei] - '0'); // from ASCII to digit
} else {
op = stack.pop(); // start with what's on the stack
switch(equation[ei]) {
case '+':
while(stack.size()) {
op += stack.pop();
}
stack.push(op);
break;
case '-':
while(stack.size()) {
op -= stack.pop();
}
stack.push(op);
break;
case '*':
while(stack.size()) {
op *= stack.pop();
}
stack.push(op);
break;
case '/':
while(stack.size()) {
op /= stack.pop();
}
stack.push(op);
break;
default:
throw std::runtime_error("invalid operation");
}
}
}
result = stack.pop();
if(stack.size() != 0)
throw std::runtime_error("stack not empty when calculation ended");
std::cout << result << '\n';
} catch(const std::exception& ex) {
std::cerr << "Exception: " << ex.what() << '\n';
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.