Swap 2 values of a stack does not work - c++

#include <iostream>
#include <string.h>
using namespace std;
#define NMAX 10 // pre-processing directive
template<typename T>
class Stack {
public:
T Smain, Saux;
T stackArray[NMAX];
int topLevel;
int getTopLevel()
{
return this->topLevel;
}
void push(T x)
{
if (topLevel >= NMAX - 1)
{
cout<<"The stack is full: we have already NMAX elements!\n";
return;
}
stackArray[++topLevel] = x;
}
int isEmpty()
{
return (topLevel < 0);
}
T pop()
{
if (isEmpty()) {
cout<<"The stack is empty! \n";
T x;
return x;
}
return stackArray[topLevel--];
}
T peek()
{
if (isEmpty())
{
cout<<"The stack is empty! \n";
T x;
return x;
}
return stackArray[topLevel];
}
void afficher() {
cout<<"On affiche la pile:";
for ( int i=0; i<=topLevel; i++ )
cout<<stackArray[i]<<" ";
cout<<endl;
}
Stack()
{
topLevel = -1;
}
~Stack() {
}
void change(int i)
{
while (Smain.topLevel>i){
Saux.push(Smain.pop());}
T aux1=Smain.pop();
T aux2=Smain.pop();
Smain.push(aux1);
Smain.push(aux2);
while (Saux.topLevel>=0){
Smain.push(Saux.pop());}
}
};
int main()
{
Stack<int> stack1;
Stack<int> stack2;
stack1.push(1);
stack1.push(2);
stack1.push(3);
stack1.push(4);
change(3);
stack1.afficher();
return 0;
}
This program has to swap the i and i-1 position of a stack, but i get the error: 'change' was not declared in this scope and i don't know how to make it work. please help me and thanks to you in advance.

change is declared inside the class Stack, so it becomes a method on a Stack instance.
You probably want to call it as stack1.change(3) instead.

You cannot call change() function which is inside a class directly.instead use an class object to call it.
class stack{
}objectname;
int main(){
objectname.change(3);
}

Related

C++, "friend class" that's defined in the same header

I'm following this tutorial to create a simple iterator, although they are iterating primitive int, I'm iterating an object type SpamValue.
I have class called SpamValue and another called SpamValueStackIter and they are tightly coupled, because I didn't want to expose a lot of getters, so I made one class SpamValueStackIter a "friend class" in SpamValue header.
#ifndef SPAMSTACK_H
#define SPAMSTACK_H
#include <iostream>
#include "SpamValue.h"
using namespace std;
class SpamStack
{
public:
friend class SpamValueStackIter;
SpamStack(SpamValue** SpamValueItems, int size)
{
_position =-1;
_total_size = size;
_SpamValueItems = new SpamValue*[_total_size];
int i=0;
for (; i<_total_size; i++)
{
this->_SpamValueItems[i] = SpamValueItems[i];
}
}
~SpamStack()
{
if (NULL!=_SpamValueItems)
{
/*delete each*/
int i =0;
for (; i<_total_size; i++)
{
if (NULL!=_SpamValueItems[i])
{
delete _SpamValueItems[i];
}
}
/*delete the array*/
delete [] _SpamValueItems;
}
}
/*push*/
void push(SpamValue* SpamValue)
{
_SpamValueItems[++_position];
}
/*pop*/
SpamValue* pop()
{
return _SpamValueItems[_position--];
}
/*isEmpty*/
bool isEmpty()
{
return (_position == -1);
}
/*getters*/
SpamValue** getSpamValueItems()
{
return this->_SpamValueItems;
}
int getTotalSize()
{
return _total_size;
}
SpamValueStackIter* createIterator()const;
private:
SpamValue** _SpamValueItems;
int _total_size;
int _position;
};
class SpamValueStackIter
{
const SpamStack* _stack;
int _index;
public:
SpamValueStackIter(const SpamStack *s)
{
_stack = s;
}
/*set index position to first item*/
void first()
{
_index = 0;
}
/*set index position to the next item in the iterator*/
void next()
{
_index++;
}
/*is the iteration completed */
bool isDone()
{
return _index == _stack->_position + 1;
}
/* return the current item */
SpamValue* currentItem()
{
return _stack->_SpamValueItems[index];
}
/*create a new iterator*/
SpamValueStackIter* SpamStack::createIterator()const
{
return new SpamValueStackIter(this);
}
};
#endif /* SPAMSTACK_H*/
In the SpamStack.h:, Im getting this error:
SpamStack.h:77:6: error: ‘SpamValueStackIter’ does not name a type
SpamValueStackIter* createIterator()const;
And also:
SpamStack.h:121:52: error: cannot define member function ‘SpamStack::createIterator tor’ within ‘SpamValueStackIter’
SpamValueStackIter* SpamStack::createIterator()const
Why can't SpamStack resolve the "friend class" that's defined in the same header?
After forward declaration, as suggested by others:
#ifndef SPAMSTACK_H
#define SPAMSTACK_H
#include <iostream>
#include "SpamValue.h"
using namespace std;
/*forward declare*/
class SpamValueStackIter;
class SpamStack
{
public:
friend class SpamValueStackIter;
SpamStack(SpamValue** SpamValueItems, int size)
{
_position =-1;
_total_size = size;
_SpamValueItems = new SpamValue*[_total_size];
int i=0;
for (; i<_total_size; i++)
{
this->_SpamValueItems[i] = SpamValueItems[i];
}
}
~SpamStack()
{
if (NULL!=_SpamValueItems)
{
/*delete each*/
int i =0;
for (; i<_total_size; i++)
{
if (NULL!=_SpamValueItems[i])
{
delete _SpamValueItems[i];
}
}
/*delete the array*/
delete [] _SpamValueItems;
}
}
/*push*/
void push(SpamValue* SpamValue)
{
_SpamValueItems[++_position];
}
/*pop*/
SpamValue* pop()
{
return _SpamValueItems[_position--];
}
/*isEmpty*/
bool isEmpty()
{
return (_position == -1);
}
/*getters*/
SpamValue** getSpamValueItems()
{
return this->_SpamValueItems;
}
int getTotalSize()
{
return _total_size;
}
SpamValueStackIter* createIterator()const;
private:
SpamValue** _SpamValueItems;
int _total_size;
int _position;
};
class SpamValueStackIter
{
public:
SpamValueStackIter(const SpamStack *s)
{
_stack = s;
}
/*set index position to first item*/
void first()
{
_index = 0;
}
/*set index position to the next item in the iterator*/
void next()
{
_index++;
}
/*is the iteration completed */
bool isDone()
{
return _index == _stack->_position + 1;
}
/* return the current item */
SpamValue* currentItem()
{
return _stack->_SpamValueItems[index];
}
private:
const SpamStack* _stack;
int _index;
};
/create a new iterator/
SpamValueStackIter* SpamStack::createIterator()const
{
return new SpamValueStackIter(this);
}
#endif /* SPAMSTACK_H */
In getting this error now:
SpamStack.h:117:45: error: invalid types ‘SpamValue** const[<unresolved overloaded function type>]’ for array subscript
return _stack->_SpamValueItems[index];

Push/pop stack class program in C++?

I've written and modified an example code from a C++ book about pushing/popping numbers off a stack class. This is a basic question just for my understanding.. Here is the code.
//stakarray.cpp
//a stack as a class
#include <iostream>
using namespace std;
class Stack
{
private:
enum { MAX = 10 };
//int MAX=10;
int st[MAX];
int top;
public:
Stack()
{ top=0; }
void push(int var)
{ st[++top]=var; } //increments stack, input var
int pop()
{ return st[top--]; } //returns var, decrements stack
void show(int var)
{ cout << st[var]<< endl; }
};
int main()
{
//some stack operations
int i;
Stack s1;
s1.push(11);
s1.push(22);
cout<<"1: "<<s1.pop()<<endl; //22
cout<<"2: "<<s1.pop()<<endl; //11
s1.push(33);
s1.push(44);
s1.push(55);
s1.push(66);
for (i=0; i<= 10 ; i++)
{
cout<< "s1[" << i << "]= ";
s1.show(i);
}
return 0;
}
The output of this program gives
1: 22
2: 11
s1[0]= 2
s1[1]= 33
s1[2]= 44
s1[3]= 55
s1[4]= 66
s1[5]= 0
s1[6]= 0
s1[7]= 0
s1[8]= 4196896
s1[9]= 0
s1[10]= 4
Why is s1[0]=2, s1[8]=4196896, s1[10]=4? Is there also any way to access MAX from private or do i have to define it somewhere else in the class (not using as global variable or part of main())?
Element 0 is never used, because in push you use pre-increment (++top) instead of post-increment (top++).
Your stack has at most 4 elements in it at a time, therefore all elements following index 4 have undefined content (i.e., random garbage in s1[5]...s1[10]).
In your code you were incrementing top with a pre-increment ++top before setting the value. Therefore, top would go to 1 and then you would set s1[1]=33. If you switch to post-increment top++, your counter variable top will increment after setting s[0]=33.
//stakarray.cpp
//a stack as a class
#include <iostream>
using namespace std;
class Stack
{
private:
enum { MAX = 10 };
//int MAX=10;
int st[MAX];
int top;
public:
Stack()
{ top=0; }
void push(int var)
{ st[top++]=var; } //increments stack, input var
int pop()
{ return st[top--]; } //returns var, decrements stack
void show(int var)
{ cout << st[var]<< endl; }
};
int main()
{
//some stack operations
int i;
Stack s1;
s1.push(11);
s1.push(22);
cout<<"1: "<<s1.pop()<<endl; //22
cout<<"2: "<<s1.pop()<<endl; //11
s1.push(33);
s1.push(44);
s1.push(55);
s1.push(66);
for (i=0; i<= 10 ; i++)
{
cout<< "s1[" << i << "]= ";
s1.show(i);
}
return 0;
}

Inheriting from the stack class

Hi guys I did not know how to title this properly. The query I have is with the implementation of a stack I made. In the code I would assume we could use this->push() or this->pop() but the scope operator is needed(stack::push).. I do not understand Why?
#include <iostream>
#include <stack>
template <class T >
class SpecialStack : std::stack<T>
{
public:
SpecialStack() : isEmpty(true) {};
void push(T element)
{
if (!isEmpty)
{
T LastMin = min_stack.top();
if (element < LastMin)
{
min_stack.push(element);
}
else
{
min_stack.push(LastMin);
}
}else
{
min_stack.push(element);
}
stack::push(element); // works
//this->push(element); // Unhandled Exception
}
T pop()
{
min_stack.pop();
T out = stack::top();
stack::pop();
return out;
}
T getMin()
{
return min_stack.top();
}
private:
std::stack<T> min_stack;
bool isEmpty;
};
int main()
{
SpecialStack<int> s;
s.push(3);
s.push(2);
s.push(1);
s.push(5);
s.push(6);
//cout << s.getMin() << endl;
s.pop();
s.pop();
s.pop();
std::cout << s.getMin() << std::endl;
system("pause");
}
void push(T element) {
...
this->push(element);
}
The last line calls your push function recursively. Since the process never terminates, you are getting your stack overflow exception.
stack::push is the correct way to tell the compiler you want to call an implementation from the parent class.

Popping the top 2 values from a stack, adding them and push them back

Here's what I came up with, I just want the program to pop the first 2 values in the stack, calculate them and push the back into the stack...I've already created the functions required but there seem to be a problem with the function that adds the two numbers.
#include <iostream>
using namespace std;
int Maxlenght=5;
class stackhouse{
private:
int *CreateArray;
int top;
public:
stackhouse();
bool IsEmpty();
bool IsFull();
void constructor();
void Push(int);
void Pop(int);
void Sum();
void Sub();
};
stackhouse::stackhouse(){
CreateArray= new int[Maxlenght];
top=-1;
}
bool stackhouse::IsEmpty()
{
if (top==-1) return 1;
else return 0;
}
bool stackhouse::IsFull(){
if (top==Maxlenght-1) return 1;
else return 0;
}
void stackhouse::Push(int number){
top++;
CreateArray[top]=number;
}
void stackhouse::Pop (int number){
number=CreateArray[top];
top--;
}
void stackhouse::Sum(){
int number=7,sum=5;
Pop(sum);
Pop(number);
sum+=number;
Push(sum);
cout<<sum;
}
void main(){
int number;
stackhouse stack1;
stackhouse();
cout<<"Please fill the stack...";
stack1.Push(5);
stack1.Push(2);
cout<<"The sum is...";
stack1.Sum();
}
The Pop function needs to either return number or pass number by reference; otherwise, the assignment to number has no effect.
void stackhouse::Pop(int& number) { // <-- add the &
number = CreateArray[top];
top--;
}
Or
int stackhouse::Pop() {
int number = CreateArray[top];
top--;
return number;
}
(Note that the second way requires you to write sum = Pop() instead of Pop(sum).)
Passing a parameter by value to the pop() method is pointless. It needs to return a value.

why visual c++ 2010 does not show me heap[i].left and heap[i].right options?

here is my interval heap implementation,code is below
#include <iostream>
#include<algorithm>
using namespace std;
template <class T> class IntervalHeap;
template <class T>
class TwoElement
{
friend class IntervalHeap <T>;
public:
T left,
right;
};
template<class T>
class IntervalHeap
{
public:
IntervalHeap(int heapsize=10);
~IntervalHeap(){delete[] heap;}
int size()const { return currentsize;}
T Min()
{
if (currentsize==0)
// throw OutOfBounds();
return heap[1].left;
}
T Max() {
if(currentsize==0)
//throw OutOfBounds();
return heap[1].right;
}
IntervalHeap<T>& Insert(const T& x);
IntervalHeap<T>& DeleteMin(T& x);
IntervalHeap<T>& DeleteMax(T& x);
private:
int currentsize;//number of elemnts in heap
int Maxsize;//max elements permited
TwoElement<T>*heap;//element array
};
template<class T>
IntervalHeap<T>::IntervalHeap(int currentsize)
{
Maxsize=heapsize;
//determine number of array positions needed
//array will be heap[0:n-1];
int n=Maxsize/2+Maxsize%2+1;
heap=new TwoElement<T>[n];
currentsize=0;
}
template<class T>
IntervalHeap<T>& IntervalHeap<T>::Insert(const T& x)
{
if (currentsize==Maxsize)
exit(1);
if (currentsize<2)
{
if(x<heap[1].left)
heap[1].left=x;
else heap[1].right=x;
else
{
heap[1].left=x;
heap[1].right=x;
}
curentsize++;
return *this;
}
int lastnode=currentsize/2+currentsize%2;
bool minHeap;
if (currentsize%2)
if (x<heap[lastnode].left)
minHeap=true;
else
{
lastnode++;
if (x<=heap[lastnode/2].left)
minheap=true;
else
minheap=false;
}
if (minHeap) //fix min heap interval heap
{
int i=lastnode;
while (i!=1 && x<heap[i/2].left){
heap[i].left=heap[i/2].left;
i/=2;
}
heap[i].left=x;
currentsize++;
if (currentsize%2)
heap[lastnode].right=heap[lastnode].left;
}
else
{
int i=lastnode;
while(i!=1 && x>heap[i/2].right){
heap[i].right=heap[i/2].right;
i/=2;
}
heap[i].right=x;
currentsize++;
if (currentsize%2)
heap[lastnode].left=heap[lastnode].right;
}
return *this;
}
template<class T>
IntervalHeap<T>& IntervalHeap<T>::DeleteMax(T &x)
{
if (currentsize==0)
exit(1);
x=heap[1].right;
int lastnode=currentsize/2+currentsize%2;
T y;
if (currentsize %2)
{
y=heap[lastnode].left;
lastnode--;
}
else{
y=heap[lastnode].right;
heap[lastnode].right=heap[lastnode].left;
}
currentsize--;
int i=1,ci=2;
while(ci<lastnode){
if (ci<lastnode && heap[ci].right<heap[ci+1]) ci++;
if (y>=heap[ci].right) break;
//can't put y in heap[i]
heap[i].right=heap[ci].right;
if (y<heap[ci].left)
::swap(y,heap[ci].left);
i=ci;
ci*=2;
}
heap[i].right=y;
return *this;
}
template<class T>
IntervalHeap<T>& IntervalHeap<T>::DeleteMin(T &x)
{
if (currentsize==0)
exit(1);
x=heap[1].left;
int lastnode=currentsize/2+currentsize%2;
T y;
if (currentsize%2)
{
y=heap[lastnode].left;
lastnode--;
}
else
{
y=heap[lastnode].right;
heap[lastnode].right=heap[lastnode].left;
}
currentsize--;
int i=1;
int ci=2;
while(ci<=lastnode) //find place for y
{
if (ci<lastnode && heap[ci].left>heap[ci+1].left) ci++;
if (y<=heap[ci].left) break;
heap[i].left=heap[ci].left;
if (y>heap[ci].right)
::swap(y,heap[ci].right);
i=ci;
ci*=2;
}
if (i==lastnode && currentsize%2)
heap[lastnode].left=heap[lastnode].right;
else
heap[i].left=y;
return *this
}
int main(){
return 0;
}
problem is that when i type ,heap[1]. it does not show me options (left,right) why?is it my code fault or there is some misses with c++ editior?compilator?please help me
I suspect intellisense is not working for your class because it is templated. Which version of visual studio is it? Intellisense can fail for a number of reasons, has it actually finished indexing/compiled your code, and does your code actually compile?