#include<iostream>
#include<vector>
using namespace std;
class Stack {
private:
int maxSize;
vector<int> v;
int top;
public:
Stack(int size) {
this->maxSize = size;
this->v.reserve(this->maxSize);
this->top = -1;
}
void push(int j) {
if (!(this->isFull())) {
this->v[++this->top] = j;
} else {
cout << "stack is full"<<endl;
}
}
int pop() {
if (!(this->isEmpty())) {
return this->v[this->top--];
} else {
cout << "\nstack is empty"<<endl;
cout<< "StackOverflow "<<endl;
}
}
int peak() {
return this->v[this->top];
}
bool isEmpty() {
return (this->top == -1);
}
bool isFull() {
return (this->top == this->maxSize - 1);
}
};
int main() {
Stack s(10);
s.push(10);
s.push(20);
cout<<s.pop();
cout<<"\n"<<s.pop();
s.push(40);
cout<<"\n"<<s.pop();
}
由于以下原因,如何使此代码更好,更可靠:
此代码的输出为20 10 40。
但是在输出中,我想在每次输出后打印“堆栈为空” 从堆栈中弹出所有元素之后的时间 堆栈
每次都无法打印“堆栈为空” 。
答案 0 :(得分:3)
您的代码中包含UB:
this->v[++this->top] = j;
return this->v[this->top--];
等等。您在std::vector
中保留空间的事实并不使访问大量元素合法,您无法访问元素。而且您使代码过于复杂-std::vector
保持其大小,因此根本不需要索引top
。您需要做的是push_back()
添加元素,并使用back()
访问最后一个元素,然后使用pop_back()
删除它。您可以使用std::vector>::empty()
或std::vector::size()
来检查是否还有元素。
答案 1 :(得分:2)
代码中的特定问题是由于您尝试使用std::vector
进行越界访问;其行为是 undefined 。请注意,reserve
不能使该数量的元素可供使用;只有潜在可用,而无需随后的内存重新分配。如果您使用的是at
而不是[]
,则您的C ++标准库将抛出运行时错误。
std::vector
具有push_back
和pop_back
函数,可让您合理地有效地使用它来建模堆栈。
但是,到目前为止,typedef std::stack<int> Stack;
代替所有代码是最好的方法。
请勿使用C ++标准库容器对象为C ++标准库中的其他容器建模。容器对象真的很难正确编写;并进行大量调试。
答案 2 :(得分:1)
以编程方式,仅当调用pop
时堆栈已为空时才打印“堆栈为空”,而不是当堆栈中有1个元素且仅在调用pop
之后为空时才打印。
假设堆栈上有1个元素。因此top
为0。
int pop() {
if (!(this->isEmpty())) {
此if
评估为true,因此不会打印任何内容。这是因为isEmpty()
的值为false
设置为0时,求值为top
。
您要做的是先弹出,然后然后检查堆栈是否为空。无论哪种方式,一开始都要检查它,因为您无法弹出空堆栈。