So I am doing a question in leetcode. It is Implement Stack using Queues.
If I submit this code below. It is accepted.
class Stack {
public:
queue<int> que;
// Push element x onto stack.
void push(int x) {
que.push(x);
for(int i=0;i<que.size()-1;i++){
que.push(que.front());
que.pop();
}
}
// Removes the element on top of the stack.
void pop() {
que.pop();
}
// Get the top element.
int top() {
return que.front();
}
// Return whether the stack is empty.
bool empty() {
return que.empty();
}
};
but if I only change for(int i=0;i<que.size()-1;++i) to for(int i=0;i<=que.size()-2;i++), I got Time limitation exceeded. Last executed input: push(1),empty().Could somebody tell me why??? Thanks
queue::size() returns a size_t which is basically an unsigned number. and a negative unsigned number converts to a huge number.
So queue::size()-1 --> huge number (0xFFFFFFFF)
Related
I want to make a char stack implementation, but i think something is wrong with it because when i try to use it for my other function it does not word and library stack works. Can you help to find an issue:
using namespace std;
Stack::Stack(int size)
{
arr = new char[size];
capacity = size;
t = -1;
}
int Stack::size()
{
return (t + 1);
}
Stack::~Stack()
{
delete[] arr;
}
bool Stack::empty()
{
return size()==0;
}
void Stack::push(char x)
{
if (size()==capacity) {
cout<<"Push to full stack";
arr[++t]=x;
}
}
char Stack::pop()
{
if (empty()) {
cout<<"Pop from empty stack";
--t;
}
return 0;
}
char Stack::top()
{
if (!empty())
return arr[t];
else
cout<<"Top of the stack is empty";
return 0;
}
I want to make a char stack implementation, but i think something is wrong with it because when i try to use it for my other function it does not word and library stack works. Can you help to find an issue:
Thank you in advance!
I think you need to make some changes to the push and pop function for your Stack to work
In push, you should put arr[++t]=x; outside the if statement instead of inside as you want to add value to arr if the current size is less than its capacity instead of when it is equal
In pop, you should put arr[--t]; outside the if statement instead of inside as you want to remove and return the last value in the array if the stack is not empty. When it is empty, you should consider returning a default character such as the null terminator character \0. You should also want to use arr[t--] instead of arr[--t] as the last element is currently at t so you want it to evaluate arr[t] before decreasing its value (t--)
void Stack::push(char x)
{
if (size()==capacity) {
cout<<"Push to full stack";
return;
}
arr[++t]=x;
}
char Stack::pop()
{
if (empty()) {
cout<<"Pop from empty stack";
return '\0';
}
return arr[t--];
}
So I'm just starting to learn about data structures through a course on Coursera and I learned that it's possible to create a stack data structure by using an array. I was just wondering if what I have written is what a stack is supposed to do.
#include <iostream>
using namespace std;
const int MAX_SIZE = 10000;
class Stack {
public:
Stack();
~Stack();
void push(int n);
void pop();
int top();
bool isEmpty() const;
void print() const;
private:
int* array [MAX_SIZE];
int curNum;
};
Stack::Stack() {
curNum = 0;
}
Stack::~Stack() {
for (int i = 0; i < curNum; ++i)
delete array[i];
}
void Stack::push(int n) {
if (curNum >= MAX_SIZE) {
cout << "reached maximum capacity...can't add an element\n";
return;
}
array[curNum] = new int(n);
curNum++;
}
void Stack::pop() {
delete array[curNum];
curNum--;
}
int Stack::top() {
return *array[curNum];
}
void Stack::print() const{
for (int i = 0; i < curNum; ++i)
cout << *array[i] << endl;
}
bool Stack::isEmpty() const{
return curNum == 0;
}
int main () {
Stack stack;
stack.push(5);
stack.print();
stack.pop();
}
Also, I see that a lot of people don't use dynamic memory allocation for this kind of task. Is there a reason why? It seems like specifying a size for the array at compile time might lead to insufficient memory or over-allocating memory to me
Yes, this is one way to implement a stack. The important thing that defines a stack is LIFO (last in, first out). So as long as you are only adding to and removing from the top, then that is a stack. Think of it as a stack of dishes; if 10 dishes are put one by one into a stack, and then one by one removed from said stack, the first dish put on will also be the last dish removed. You can't remove a dish that's not at the top, as it is covered by all the dishes above it. The same is true with a stack data structure.
So your implementation is indeed a stack.
The stack we use when we want something in reverse order and stack also takes constant time means O(1) time to push and pop means to remove or to add it will work much faster
#include<iostream>
#include<vector>
using namespace std;
class Stack
{
public:
int top;
vector<int> v;
Stack(int size)
{
top=0;
cout<<"Enter the values"<<endl;
for(int i=0; i<size; i++)
{
int val;
cin>>val;
v.push_back(val);
top++;
}
}
void push(int val)
{
v.push_back(val);
top++;
}
int pop()
{
int x=v[top];
top--;
return x;
}
void disp()
{
for(int j=top; j<=0; j--)
cout<<v[j]<<' ';
}
};
int main()
{
Stack s(3);
int k=s.pop();
cout<<k;
return 0;
}
I am trying to learn the basics of OOP.
Here, my Stack constructor and push function are working fine, but there is a problem with the pop and disp functions.
I'm assuming that I am using an incorrect syntax to access the elements of a vector(maybe?). Can anyone tell me where I am going wrong?
Also, the value of k always comes out to be 0.
You can use the vector functions
int k = s.back();
s.pop_back();
cout << k;
more informationhttp://www.cplusplus.com/reference/vector/vector/back/
You have a off-by-one index error.
The way you have implemented your class, when there are N items in the stack, the value of top is N.
Hence, top is not a valid index to access the elements of v. You can use:
int pop()
{
int x=v[top-1];
top--;
return x;
}
or
int pop()
{
top--;
int x=v[top];
return x;
}
As some of the other answers say, you can use the built-in vector functions to do these things (see pop_back and back.
However, if you want to define your own, I would use the vector.at(index) function. Addressing the values with the index as you have works, but it doesn't do any bounds checking at() does. Which would solve your problem above where your index isn't correct for the zero-based indexing of a vector.
OK, so I edited my code, but I still have two problems :
But here's my code first :
#include <iostream>
using namespace std;
struct stack
{
int data[5];
int top;
};
void push (int a, stack &S)
{
S.top++;
if (S.top<5)
{
S.data[S.top]=a;
}
else cout<<"Stack is full!!!"<<endl; S.top--;
}
int pop(stack &S)
{
if (S.top==-1)
{
cout<<"Stack is empty!"<<endl;
}
else
{
int temp=S.data[S.top];
S.data[S.top]=NULL;
S.top--;
return temp;
}
}
bool isEMPTY(stack &S)
{
if (S.top==-1)
return true;
else return false;
}
bool isFULL(stack &S)
{
if (S.top==5)
return true;
else return false;
}
int main()
{
stack S = { {}, -1 };
push(5,S); cout<<"5 is pushed \n"<<endl;
push(3,S); cout<<"3 is pushed \n"<<endl;
push(1,S); cout<<"1 is pushed \n"<<endl;
push(2,S); cout<<"2 is pushed \n"<<endl;
push(6,S); cout<<"6 is pushed \n"<<endl;
push(7,S); cout<<"7 is pushed \n"<<endl;
cout<<pop(S)<<"is popped\n"<<endl;
cout<<pop(S)<<"is popped\n"<<endl;
cout<<pop(S)<<"is popped\n"<<endl;
return 0;
}
So, the first problem is, when I pop I get a "Totally random value" and it's not like LIFO.
Second is, I actually intended on inserting 6 values, when I already had the max value = 5, so the output actually showed me the 6 values.
stack S;
Since stack is POD, the above line doesn't initialize the member top. As such, using an uninitialized top in push and pop functions invokes undefined behavior.
Write this:
stack S {}; //must be compiled in C++11 mode, else write : stack S = stack();
This value-initializes S and its members, which means, top is initialized to 0. The rest of the code may still have other problems, but at least you have fixed the issues with proper initialization. If you work with 0 as initial value of top, you've write the logic of push and pop accordingly!
Once you fix that, check the value of top before pushing and poping values from the stack, as the member array can have at most 5 elements, and you cannot pop more elements when it is empty. You must maintain these invariants.
I do not see where an object of type stack was created and how data member top was initialized.
Also take nto account that member function push does not check whether there is an attempt to add an item beyond the array.
You should define the object the following way
stack S = { {}, -1 };
else cout<<"Stack is full!!!"<<endl; S.top--;
is identical to :
else
{
cout<<"Stack is full!!!"<<endl;
}
S.top--;
as a general rule, try to avoid: writing if/else without curly brackets, and, avoid writing more then one line of code in the same line.
The mistake is:
stack s;//you define the local variable "s" without been intitialized.
push(5,s);//pass the uninlitialized "s" to the function "push",when debugging your code,"s.top" is not a expected "-1",but some value incredible~(often extreamly larger than 5),so your push operation failed!
stack S;
S.top = -1;
for(int i = 0; i < 5; i++)
{
S.data[i] = 0;
}
I'm trying to implement a queue with two stacks for purposes of understanding both data structures a little better. I have the below, with the main function serving as a test:
#include <iostream>
#include <stack>
using namespace std;
template <class T>
class _Stack : public stack<T> {
public:
T pop(){
T tmp=stack::top();
stack::pop();
return tmp;
}
};
template <class T>
class QueueS {
public:
QueueS(){}
bool isEmpty() const{
return pool.empty();
}
void enqueue(const T& el){
while( !output.empty()) {
input.push(output.pop());
}
input.push(el);
}
T dequeue(){
while(!input.empty()){
output.push(input.pop());
}
return output.pop();
}
T firstElement(){
if(output.empty()) {
return NULL;
}
return output.top();
}
private:
_Stack<T> pool;
_Stack<T> input;
_Stack<T> output;
};
int main(){
QueueS<int> n_QueueS;
//fill the queue of integers 0-9
for(int i=0; i<10;i++)
n_QueueS.enqueue(i);
// add another number to the queue
n_QueueS.enqueue(50);
//retrieve the first element without removing it
cout<<"front of the queue: "<<n_QueueS.firstElement()<<endl;
// removing the first 5 elements from the queue
cout<<"deleting first five elements of the queue: ";
for(int i=0; i<5;i++)
cout<<n_QueueS.dequeue()<<" ";
//removing the remainder of the queue and displaying the result
//should see 5 6 7 8 9 50 - see nothing!
cout<<endl<<"deleting remainder of the queue: ";
while(!n_QueueS.isEmpty())
cout<<n_QueueS.dequeue()<<" ";
if(n_QueueS.isEmpty())
cout<<endl<<"Queue is now empty";
else
cout<<endl<<"Error in emptying the queue";
system("pause");
return 0;
}
It works pretty well thusfar. However, when I run my test, deleting the first five elements works fine, and they display fine. It displays the line "deleting first five elements of the queue:" followed by 0 1 2 3 4, as expected.
However, deleting the second half doesn't display the values after the text "deleting remainder of the queue" like the previous test case did. I'm assuming the problem is minor, but I can't locate it through debugging. Maybe I've overlooked something?
Any help would be greatly appreciated!
First of all, your empty check should be something like this:
bool isEmpty() const{
return input.empty() && output.empty();
}
in enqueue, just push to the input stack:
void enqueue(const T& el){
input.push(el);
}
in enqueue and dequeue, move input to output if output is empty:
T dequeue(){
if (output.empty())
while(!input.empty()){
output.push(input.pop());
}
// throw exception of output.empty() ??
return output.pop();
}
T firstElement(){
if (output.empty())
while(!input.empty()){
output.push(input.pop());
}
if(output.empty()) {
return T(0); // throw exception?
}
return output.top();
}