I am stuck after popping the values from stack1 then trying to push those values back into stack1, to later push back into stack2 in order. I'm not sure if I need another loop to make it nested loops or if I should switch to for loops as they are counting loops.
void copyStack(stack<int>& stack1, stack<int>& stack2)
{
int size = stack1.size();
while(size > 0)
{
stack2.push(stack1.top());
stack1.pop();
stack1.push(stack2.top());
--size;
}
}
Example:
Stack1: 4 3 2 1
Stack2: (empty)
(after running the function...)
Stack1: (empty)
Stack2: 4 3 2 1
I'm a bit confused, why don't you just use this:
void copyStack(stack<int>& stack1, stack<int>& stack2) {
stack2 = stack1;
}
It's C++ ;)
Or, if you want to swap elements of these two stacks, instead of copying, you can use:
stack1.swap(stack2);
EDIT: if you want to do it by yourself and looking for an interesting solution, you can try these links:
Clone a stack without extra space
Clone a stack without using extra space | Set 2
If you pop the values from one stack and push them onto another, they'll be in the reverse of their original order. You need an intermediate stack if you want them in the original order. Pop all values from stack1 and push then to stackTemp, then do the same from stackTemp to stack2.
void copy(Stack<T> source)
{
Stack<T> temp1;
Stack<T> temp2;
while (!source.isEmpty())
{
temp1.push(source.peek());
temp2.push(source.peek());
source.pop();
}
while (!temp1.isEmpty())
{
push(temp1.peek());
temp1.pop();
}
while (!temp2.isEmpty())
{
source.push(temp2.peek());
temp2.pop();
}
}
Related
I need to sum up or multiplie(it depends on which operation i push in array) first two numbers in stack. If I push operation + and my first two numbers are one and two then my stack value where I pushed + must be 3 , but in my result i get some symbol.
#include<iostream>
using namespace std;
#define MAX 10
int sp=-1;
char stack[MAX];
void push(){
if(sp==MAX-1){
cout<<"Error: stack overflow"<<endl;
return;
}
else{
char x;
cout<<"Insert value in stack: ";
cin>>x;
if(x=='*'){
if(sp>=1){
stack[++sp]=stack[1]*stack[0];
return;
}
else {
stack[++sp]=x;
return;
}
}
else if(x=='+'){
if(sp>=1){
stack[++sp]=stack[0]+stack[1];
return;
}
else {
stack[++sp]=x;
return;
}
}
else stack[++sp]=x;
}
}
void pop(){
if(sp==-1){
cout<<"Error: Stack empty";
return;
}
else{
cout<<stack[sp]<<endl;
sp--;
}
}
void top(){
if(sp==-1){
cout<<"Error: Stack empty";
return;
}
else{
cout<<stack[sp]<<endl;
}
}
void isEmpty(){
if(sp==-1){
cout<<"Stack is empty"<<endl;
return;
}
else{
cout<<"Stack is not empty"<<endl;
}
}
int main(){
for(int i=0;i<8;i++){
push();
}
top();
return 0;
}
Original stack:
3 4 3 + 1 2 * *
Stack that I need to get:
3 4 3 7 1 2 12 12
Stack that I get:
3 4 3 \ 1 2 _ _ (let's say something like that)
So you wanted to implement some postfix calculator. Very good that you noticed that a stack is needed.
For calculators you normally parse the input, store some results on a stack and then operate on the stack elements.
In contrast to what timo said, a parse stack can never be implemented with a std::stack because several top stack elements must be matched against the production in the grammar. For that reason a std::vector is the ideal container.
Now to the problem in the program. OP tries to store integer values and operators like "+" and "*" and results of calculations in the same datatype char. That cannot work. char stores characters like '+' or '*' or '1' but not 1. Internally a character is also encoded as a number (for example using ASCII) and a '1' would be equal to 49. And, if you look at results you cannot store '12' (for all the pros. Yes of course I know) in a char. 12 is a number, not a character.
And if you mix these types and do calculations with that then you get wrong results.
The solutions is to use Tokens and implement them as a std::variant. The variant can have a char an an int. Then your parse stack should be a std:::vector of Token.
This the right approach.
Additionally. In all standard recursive descent parsers you do not operate always on elements 0 and 1. You would replace the used values with the newly calculated one.
There is always the same approach
Read next Token and shift it on a stack
Match the top elements of the stack against a production
Reduce. Replace used elements with result
Some example of a different parser: See here.
This is somehow complicated. You may want to read about formal languages and parser.
this is my first data structure program. I am implementing a simple stack using array with push, pop and initialize functions. I am getting an infinite loop as the output. Could you please tell me why is this so?
#include<iostream>
using namespace std;
# define SIZE 6
class stack{
public:
void init();
void push(int i);
int pop();
int top;
int stck[SIZE];//bydefault private
};
void stack::init()
{
top=0;
return;
}
void stack::push(int i)
{
if(top==SIZE)
{
cout<<"stack is full";
return;
}
else
{
top=top+1;
stck[top]= i;
return;
}
}
int stack::pop()
{
if(top==0)
{
cout<<"stack is empty. \n";
return 0;
}
else
{
top = top-1;
return(stck[top-1]);
}
}
int main()
{
stack stack1;
stack1.init();
int a;
int m;
while(a!=4)
{
cout<<"1. push 2. pop 3.display 4.exit .\n";
cin>>a;
if(a==1){
cout<< "enter value";
cin>>m;
stack1.push(m);
}
if(a==2)
{
cout<<"popped"<< stack1.pop();
}
if(a==3)
{
for(int k=0; k<=stack1.top;k++)
{
cout<<stack1.stck[k];
}
}
}
}
You never initialize a, so your program has undefined behaviour. Specifically, the while (a != 4) line performs an lvalue-to-rvalue conversion of a while its value is indeterminate, which the C++ standard explicitly states as undefined behaviour in section 4.1.
However, I doubt this is causing the issue at hand. In practice, unless the optimizer just optimized all your code out, your program should usually behave as expected; it's only when a == 4 on the first loop that you have problems. This doesn't make the code acceptable, but there's probably more to it.
I suspect the problem is that you use top to represent one past the number of elements. When you have zero elements, you point to the first; when you have one, you point to the second, etc. This means you're pointing to the first unused element.
However, in both your push and pop functions, you change top first and only then access the stack, but acting as if you didn't change it:
top = top + 1;
stck[top] = i;
When your stack is empty, this will set top to 1 and then access stck[1]. Meanwhile, stck[0] is left unset. When popping, you have the opposite:
top = top - 1;
return stck[top-1];
This sets top back to 0, but returns stck[-1], which is out of bounds.
I suspect that if you push SIZE values onto the stack, you will end up overwriting unrelated memory, which could cause all kinds of trouble. I still don't see how an infinite loop will follow, but given the behaviour is undefined, it is certainly a possible result.
(The alternative is that you at some point enter something other than a number. Seeing as you never check whether your input succeeded, if a != 4 and you enter something invalid, all further reads will fail, and a will remain unequal to 4. You could fix this by making changing your while to be
while (a != 4 && std::cin)
In that case, if you enter something invalid and std::cin goes into a non-good state, your loop (and thus program) will end.)
You only have a single loop, terminated based on user input.
If cin>>a fails, a will have whatever value it started with (undefined in your code), and you will loop on that unchanging value.
Typical ways for the input call to fail include
pressing control+D (on a *nix system)
pressing control+Z (on a Windows system)
redirected input from a pipe or file which is exhausted
There may be other causes of failed input as well.
I am having trouble figuring out how the whole pointer push and pop works. On my program the user is supposed to create a stack which is empty (NULL) and with that the user can select to either push a number on the stack or pop the number which was pushed on, off. Also it is supposed to count the number of stacks and what is stored but I'm assuming i could figure that out if i understand how push and pop is supposed to be written. I understand the concept behind those i just don't know how its supposed to be written. Someone please help me understand this. I went to a tutor but he needed to refresh his memory and told me to come back another day. Which I will, but i cannot rely on that.
Here is my implementation of pop. It should be obvious from this example what would need to be done for push. I can't say this is the most cost efficient way.
template <class T>
T SimpleStack<T>::popOff()
{
T popped = *(aptr + --arraySize); //aptr points to the existing stack
int tSize = arraySize; //arraySize is a member holding the size
T *temp = new T[tSize]; //Temp holder for the elements that stay
//on the stack
for(int i = 0; i < tSize; ++i)
{
*(temp+i) = *(aptr+i); //Fill the temp holder with the original
//stack - popped
}
delete [] aptr; //Get rid of the old stack
aptr = new T [tSize]; //Create a new stack with the new size
for(int i = 0; i < arraySize; ++i)
{
*(aptr+i) = *(temp+i); //Fill the new stack with the kept values
}
delete [] temp; //Get rid of the temp holder
return popped; //Send the popped number back
}
The fact still remains that without reading up on what a stack, or any custom container you're trying to emulate, is and how it's used and where it's best suited you'll probably struggle.
I have a queue problem. Modeling a graph, I'm doing a shortest path algorithm in C++.
In my while (!q.empty()) the front vertex* gets changed when I return to this statement.
Can you figure out why?
int MyMatrix::searchBreadth(MyVertex* from,MyVertex* to)
{
queue<MyVertex*> q;
path=INFINITY;
from->visit();
from->setDistance(0);
q.push(from);
//here q.front()'s attributes get changed when returning from the for-loop
while(!q.empty())
{
MyVertex* v=q.front();
q.pop();
int k=v->getDistance();
vector<MyVertex> nb=getNeighbours(*v);
for(int i=0;i<nb.size();i++)
{
if(nb[i].getDistance()==INFINITY)
{
nb[i].setDistance(k+1);
q.push(&nb[i]);
}
if((nb[i].getName().compare(to->getName())==0)
&& !nb[i].isVisited())
{
//path found
int j=nb[i].getDistance();
if(j<path) path=j;
}
nb[i].visit();
}
}
return path;
}
here comes getNeighbours()
vector<MyVertex> MyMatrix::getNeighbours(MyVertex &v)
{
int index=0;
for(int l=0; l<stations.size(); l++ )
{
if(stations[l].getName().compare(v.getName())==0)index=l;
}
vector<MyVertex> out;
for(int k=0;k<matrixSize;k++)
{
if(matrix[index][k].getName().compare("null")!=0)
{
out.push_back(matrix[index][k].getTo());
}
}
return out;
}
Your problem is subtle, but related to q.push(&nb[i]). What you're doing is adding a pointer to a location in a vector, which is not conceptually the same as adding a pointer to a MyVertex object. The vector of neighbors contains the MyVertex objects "by value" (if that helps in your understanding of the problem).
A look at nb in memory may help:
0 1 I
nb [MyVertex0|MyVertex1| ... |MyVertexI]
+---------+
| (Notice it is NOT pointing to MyVertex1!)
&nb[1]------------+
When you push &nb[1] you're pushing the address nb + (1 * sizeof(MyVertex)). nb is declared on the stack, so that address is going to be somewhere on the stack.
So when your for-loop comes back around, nb gets refreshed (so to speak) and new data is added. However, your queue q contains addresses into nb that are no longer valid!
Simply put: your queue is referencing a LOCATION in the vector, not the DATA in the vector.
If you want to keep your method as-is, this means getNeighbors needs to change to return a vector of MyVertex*.
You should simply edit BreadthFirstSearch to take two MyVertex&, rather than pointers. You would then change q to be a queue<MyVertex>, v to MyVertex, and finally you should change q.push(&nb[i]) to just q.push(nb[i]).
I've been thinking about a program logic, but I cannot draw a conclusion to my problem.
Here, I've implemented stack and queue operations to a fixed array.
int A[1000];
int size=1000;
int top;
int front;
int rear;
bool StackIsEmpty()
{
return (top==0);
}
bool StackPush( int x )
{
if ( top >= size ) return false;
A[top++] = x;
return true;
}
int StackTop( )
{
return A[top-1];
}
bool StackPop()
{
if ( top <= 0 ) return false;
A[--top] = 0;
return true;
}
bool QueueIsEmpty()
{
return (front==rear);
}
bool QueuePush( int x )
{
if ( rear >= size ) return false;
A[rear++] = x;
return true;
}
int QueueFront( )
{
return A[front];
}
bool QueuePop()
{
if ( front >= rear ) return false;
A[front++] = 0;
return true;
}
It is presumed(or obvious) that the bottom of the stack and the front of the queue is pointing at the same location, and vice versa(top of the stack points the same location as rear of the queue).
For example, integer 1 and 2 is inside an array in order of writing. And if I call StackPop(), the integer 2 will be popped out, and if I call QueuePop(), the integer 1 will be popped out.
My problem is that I don't know what happens if I do both stack and queue operations on the same array. The example above is easy to work out, because there are only two values involved. But what if there are more than 2 values involved?
For example, if I call
StackPush(1);
QueuePush(2);
QueuePush(4);
StackPop();
StackPush(5);
QueuePop();
what values will be returned in the order of bottom(front) from the final array?
I know that if I code a program, I would receive a quick answer. But the reason I'm asking this is because I want to hear a logical explanations from a human being, not a computer.
ADDED:
For the second example, I have 4 candidates.
25
12
24
45
or no answer from here at all.
Why are you implementing these on the same array? The elements of one structure might overwrite those from the other if you do it like this.
You essentially have (something resembling) a deque there however, but it's difficult to run your program by hand because you have different pointers for the two data structures but only one array for both of them.
It is presumed(or obvious) that the bottom of the stack and the front of the queue is pointing at the same location, and vice versa(top of the stack points the same location as rear of the queue).
Well, ok in this case, but you should just use a Deque, which doesn't work on this assumption. Or use different vectors for the queue and stack.
Generally a human does this is just how a computer does it. Just have your program print the contents of A after each operation, and it should be logical enough.
In the case of your code, it will probably not do what you expect since the stack routines and the queue routines maintain different variables for where to push to.
StackPush(1); // place 1 at position 0; increase top of stack to 1
QueuePush(2); // place 2 at position 0; increase rear of queue to 1
QueuePush(4); // place 4 at position 1; increase rear of queue to 2
StackPop(); // get value(2) from position 0; decrease top of stack to 0
StackPush(5); // place 5 at position 0; increase top of stack to 1
QueuePop(); // get value(5) from position 0; increase front of queue to 1
If you instead wrote the code so that the stack use rear instead of top, then you would see these results.
StackPush(1); // place 1 at position 0; increase rear to 1
QueuePush(2); // place 2 at position 1; increase rear to 2
QueuePush(4); // place 4 at position 2; increase rear to 3
StackPop(); // get value(4) from position 2; decrease rear to 2
StackPush(5); // place 5 at position 2; increase rear to 3
QueuePop(); // get value(1) from position 0; increase front to 1
I'm not sure exactly what problem you're trying to solve, but this looks very much like a double-ended queue. Depending on the problem you're trying to solve, a circular buffer may be worth examining.
Have a look at those proven data structures to at least give yourself more context for implementing your own data structure, and hopefully one of them is what you're after.
the result will be 4 and 1, because the array has 1 2 4 and when you say stack pop it gets the recently added item which is 4. and when after the stack push 5 the array will be 1 2 5 and then when you pop from the queue you will get 1 as queue pop gets the first added item.