Inheriting from the stack class - c++

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.

Related

Queue using two stacks in C++

I have a working implementation for the classic "Queue using two stacks" data structure in C++ and am wondering what the best software engineering practice would be for handling const correctness.
The peek() function returns the value at the front of the queue, which may mean that we need to pop everything from one stack and copy it to the other. One way to use the copy function is to cast the constness away for this as shewn below. Is there a better way?
class MyQueue {
stack <int> s1;
stack <int> s2;
public:
MyQueue() {
}
void push(int x) {
s1.push(x);
}
void copy()
{
while (!s1.empty()) {
s2.push(s1.top());
s1.pop();
}
}
int pop() {
int res;
if (s2.empty()) copy();
if (! s2.empty()) {
res = s2.top();
s2.pop();
}
return res;
}
int peek() const {
if (s2.empty()) ((MyQueue*) (this))->copy();
return s2.top();
}
bool empty() const {
return s1.empty() && s2.empty();
}
};
It's better to adjust the design a bit, so that s2 is never empty unless the queue is empty. Then the difficult question goes away, and the code gets simpler, too:
class MyQueue {
stack <int> s1;
stack <int> s2;
public:
MyQueue() {
}
void push(int x) {
if (s2.empty()) {
// queue is empty
s2.push(x);
} else {
s1.push(x);
}
}
int pop() {
int res = s2.pop();
if (s2.empty())
copy();
return res;
}
int peek() const {
return s2.top();
}
bool empty() const {
return s2.empty();
}
private:
void copy()
{
while (!s1.empty()) {
s2.push(s1.pop());
}
}
};

Problem with throw exceptions when stack are empty ..... Queue / stack implementation

I need to throw an exception when both stacks are empty but i dont know how I should write it.
I have to implement a queue with 2 stacks!
this is main
#include "QueueFromStacks.h"
int main()
{
/* THIS IS JUST TO SHOW YOU HOW #include <stack> WORKS
stack<int> st1;
stack<int> st2;
cout << "Size before push:" << st2.size() << "\n";
st2.push(2);
st2.push(5);
cout << "Size after two pushes:" << st2.size() << "\n";
cout << st2.top() << "\n";
st2.pop();
cout << "Size of st2 after one pop:" << st2.size() << "\n";
st1.push(st2.top());
st2.pop();
cout << "Size of st1:" <<st1.size()<< " Size of st2:"<< st2.size();
*/
QueueFromStacks<int> qfs;
qfs.QueueFromStacks();
qfs.enqueue(1);
qfs.enqueue(2);
qfs.enqueue(3);
qfs.dequeue();
cout << "Queue Front : " << (qfs.front())<< endl;
// You have to implement QueuefromStack
// The logic of the queue remains the same(FIFO) but you have to use the two stacks to store your elements
// In the main program create a queuefromstack object and use your implemented methods to clearly show us what u did
return 0;
}
HEADER FILE
#ifndef QUEUEFROMSTACKS_H_
#define QUEUEFROMSTACKS_H_
#include <iostream>
#include <stack>
#include <string>
using namespace std;
class QueueEmptyException{
public:
QueueEmptyException();
~QueueEmptyException();
string getMessage() { return "Queue is empty"; }
};
template <typename E>
class QueueFromStacks
{
public:
QueueFromStacks();
~QueueFromStacks();
int size() const;
bool empty() const;
const E& front() const throw(QueueEmptyException);
void enqueue (const E& e);
void dequeue() throw(QueueEmptyException);
private:
stack<E> st1;
stack<E> st2;
int numElements;
};
#endif /* QUEUEFROMSTACKS_H_ */
IMPLEMENTATION
#include "QueueFromStacks.h"
template <typename E>
QueueFromStacks<E>::QueueFromStacks()
{
numElements = 0;
}
template <typename E>
QueueFromStacks<E>::~QueueFromStacks()
{
// TODO Auto-generated destructor stub
}
template <typename E>
int QueueFromStacks<E>::size() const
{
return numElements;
}
template <typename E>
bool QueueFromStacks<E>::empty() const
{
return (size() == 0);
}
template <typename E>
const E& QueueFromStacks<E>::front() const
throw(QueueEmptyException)
{
return st2.top(); // don't forget to check for empty and throw exception if it is empty.
}
template <typename E>
void QueueFromStacks<E>::enqueue (const E& e)
{
st2.push(e);
numElements++;
}
template <typename E>
void QueueFromStacks<E>::dequeue()
throw(QueueEmptyException)
{
**// if both stacks are empty // here i dont know what should i put as a throw condition
if (st1.empty() && st2.empty())
{
throw;
}**
// if the second stack is empty, move elements from the first stack to it
if (st2.empty())
{
while (!st1.empty())
{
st2.push(st1.top());
st1.pop();
}
// or make a call to swap(s1, s2)
}
// return the top item from the second stack
int top = st2.top();
st2.pop();
numElements--;
}
You need to change this:
void QueueFromStacks<E>::enqueue (const E& e)
{
st2.push(e);
numElements++;
}
to this:
void QueueFromStacks<E>::enqueue (const E& e)
{
st1.push(e);
numElements++;
}

Why do i get a linker error,when everything is in one file?

I get a LNK 2019 error in VS.
I have read a couple of similiar problems,but could not understand what i should do.As much as i understood VS can't find the template class code for some reason.I am not sure.
#include "pch.h"
#include <iostream>
#include <assert.h>
template<typename T>
struct item {
item* pointer = nullptr;
T value;
};
template <typename T>
class stack {
private:
item<T>* top;
public:
stack() { top = nullptr; };
~stack();
void push(const T& s) {
item<T>* p = top;
top = new item<T>;
assert(top != nullptr);
top->value = s;
top->pointer = p;
std::cout << "The item has been pushed." << std::endl;
}
void pop() {
T s;
if (!top) {
std::cout << "The stack is empty." << std::endl;
}
else {
s = top->value;
item<T>* p = top;
top = top->pointer;
delete p;
std::cout << "The item has been popped." << std::endl;
}
};
void check() {
if (!top) { std::cout << "The stack is empty." << std::endl; }
else { std::cout << "It has elements in it." << std::endl; }
}
};
int main()
{
stack<int> test;
return 0;
}
I want afterwards to be able to push and pop elements.So that i can continue on with my project.
You have declared a destructor for stack here:
~stack();
but you don't define it. Change the above to
~stack() { /* Clean up resources here. */ }
and it should work.
In C++, if you declare a destructor, you have to define it. Even if the destructor is pure virtual, you still have to define it or else you'll get linker error, as is the case here. If you are fine with the default destructor, but still want to declare it for some reason, for instance, to make it virtual, you can use the keyword default:
virtual ~stack() = default;
You can learn more about the default keyword here.

pop_back() not working

I have the following main program that creates a Stack object, fills it with doubles and then pops them. The code files fine, but the pop_back() part does not seem to work, while s.back() does return the correct value. How is this possible?
#include "Stack.h"
#include <iostream>
#include <deque>
using namespace std;
int main() {
Stack<double> s(0,0.0);
// Write doubles into Stack
int i ;
for (i=0 ; i<15 ; i++) {
s.push(i*i) ;
}
// Read doubles back from fifo
while (!s.empty()) {
double val = s.pop() ;
std::cout << "Popping value " << val << " from stack" << std::endl ;
}
return 0 ;
}
My header file looks like this, where I have omitted parts which are not relevant to the question.
#ifndef STACK_H
#define STACK_H
#include <iostream>
#include <deque>
template<class T>
class Stack {
public:
Stack(int len, T defval): s(len+1, defval) {
return;
}
~Stack() {
//delete [] s;
}
void push(T c) {
s.push_back(c);
}
T pop() {
return s.back();
s.pop_back();
}
private:
std::deque<T> s; //Array<T> s;
};
#endif
T pop() {
return s.back();
// ^^^^^
s.pop_back(); // <- unreachable!
}
When you return from a function, all the subsequent instruction will never be executed.
Store s.back()'s result in a temporary variable instead:
T pop() {
auto back = s.back();
s.pop_back();
return back;
}

Swap 2 values of a stack does not work

#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);
}