Copy elements from queue to stack - c++

I want to write a code that copies queue elements in to a stack, and this copied elements should be sorted in the stack.
i've written the code below:
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,x;
queue<int> q;
stack<int> s;
cin >> n;
for(int i=0;i<n;i++){
cin >> x;
q.push(x);
}
while(!q.empty()){
if(s.empty()){
s.push(q.front());
q.pop();
}
else{
if(q.front()>=s.top()){
s.push(q.front());
q.pop();
}
else{
while(q.front()<s.top() && !s.empty()){
q.push(s.top());
s.pop();
}
}
}
}
while(!s.empty()){
cout << s.top() << " ";
s.pop();
}
return 0;
}
but for some test cases like:3 1 2 3,the code does not seem to work.
please help me to figure out the problem with my code.

Your code seems to have a logic error in your inner while loop. You test s.top() before you test for s.empty(), which is the wrong order. s.top() is invalid if s.empty() is true. However, the exercise can be resolved relatively easily as described below.
You can retrieve the underlying container of a container adapter using the following helper:
template <class ADAPTER>
typename ADAPTER::container_type & get_container (ADAPTER &a)
{
struct hack : ADAPTER {
static typename ADAPTER::container_type & get (ADAPTER &a) {
return a.*&hack::c;
}
};
return hack::get(a);
}
Then, after populating the queue, you can copy the contents directly to the stack's underlying container, and sort it.
auto &qc = get_container(q);
auto &sc = get_container(s);
sc.assign(qc.begin(), qc.end());
std::sort(sc.begin(), sc.end());

You have to do what is essentially a selection sort: go through the queue N times, each time selecting the largest element to push onto the stack. The general idea is:
queue = queue containing items
stack = new empty stack
while queue.count > 0
// push the first item from the queue onto the stack
stack.push(queue.pop())
count = queue.count
// for each item remaining in the queue
for (i = 0; i < queue.count; ++i)
// if the item from the queue is larger than what's on the stack,
// then remove the item from the stack and put it back in
// the queue. And put the item from the queue onto the stack.
if (queue.peek() > stack.peek())
queue.push(stack.pop())
stack.push(queue.pop())

Related

how to reverse a stack using recursion in C++

I am trying to reverse stack without using extra space through recursion. But unable to find my error.
Here is my code. It is printing the same stack again.
#include<iostream>
#include<stack>
using namespace std;
void insert( stack<int>& k , int j){
k.push(j);
}
void reverse(stack<int> &s){
if(s.empty()){
return;
}
int temp = s.top();
s.pop();
reverse(s);
insert(s,temp);
}
int main()
{
stack<int>s;
for( int i = 5;i>0;i--){
s.push(i);
}
reverse(s);
while(!s.empty()){
cout << s.top() << " ";
s.pop();
}
return 0;
}
Your insert() function is incorrect since you only push temp into the stack and once the stack is empty the value of temp will be 5 so 5 is pushed then 4 and so on. Hence the stack is filled in the same order. This insert() should work.
void insert( stack<int>& k , int j){
if(k.empty()){
k.push(j);
return;
}
int temp = k.top();
k.pop();
insert(k, j);
k.push(temp);
}
insert() just inserts j to the bottom of the stack.
Your recursivity is not correct. You remove the top, call the same function (reverse) recursively and then push it back on top. This does not change its position! The same applies to all elements recursively: they do not change their position. A pure recursive solution (without using another stack or any data structure like an array or a list) to your problem is impossible.

Function that will leave the smallest occurrences at the bottom of stack

I am trying to write a stack so that all of the occurrences of the smallest element are at the bottom of the stack, while the order of the other elements stays the same. For example, if I have the stack [4,3,1,5,8,1,4] it will become [4,3,5,8,4,1,1], but my problem is that the order changes
so i will get something like this[4,5,3,4,8,1,1]
#include <iostream>
#include <stack>
using namespace std;
void minstack(stack<int> &s)
{
stack<int> t1,t2;
int count=0,min;
if(!s.empty())
{
while(!s.empty())
{
if(s.top() <min)
{ min=s.top();
count=0;
}
t1.push(s.top()); s.pop();
count++;
}
for(int i = 0 ; i<count;i++)
{
s.push(min);
}
while(!t1.empty())
{
if(t1.top()!=min);
{ s.push(t1.top());
}
t1.pop();
}
}
}
int main()
{
stack <int> s;
s.push(4);
s.push(3);
s.push(1);
s.push(5);
s.push(8);
s.push(1);
s.push(4);
minstack(s);
while(!s.empty())
{
cout<<s.top()<<" "; s.pop();
}
}
Here's an idea. First we'll need to find the smallest element of the stack. Define a temporary stack t. We'll now pop all elements one by one from s and push them into t. At the same time, keep track of the minimum value min and the number of times it has been encountered so far in the popping process in count. Once this is done, notice that you'll have the reverse order of elements in t and have min and count. Now we'll push count number of elements of value min back into s. Then start popping and pushing from t to s except for the elements which equal min.

C++- How to increase stack size to allow more recursion for Kosaraju's Algorithm to compute Strongly Connected Components

I am using a mac, 4GB of RAM and CLion IDE. Compiler is Clang. I need to allow more recursion in this recursive implementation of Depth First Search (currently fails on a graph with 80k nodes).
typedef unordered_map <int, vector<int>> graph;
void DFS (graph &G, int i, vector <bool> &visited) {
visited[i] = true;
for (int j = 0; i < G[i].size(); j++) {
if (!visited[G[i][j]]) {
DFS(G, G[i][j], visited);
}
}
t++;
finishingTime[t] = i; //important step
}
This is for an implementation of Kosaraju's algorithm to compute strongly connected components in a graph. https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm I know it is possible to implement DFS as iterative instead but the last step is important, and I can't find a way to include it using iteration. This is because that step is done when DFS fails and backtracking occurs, and recursion provides a very natural way to do this.
So currently I have only two options:
Increase the stack size to allow more recursion
Or find an iterative solution
Any ideas how to do either?
As suggested by a comment you can put each call to DFS on a stack allocated on heap made from the parameter list of DFS and then iterate through the stack. Each entry in the stack is essentially a task.
Pseudo-like code:
Start and run "recursion":
nr_of_recursions = 0;
dfs_task_stack.push(first_task_params)
while dfs_task_stack not empty
DFS(dfs_task_stack.pop)
nr_of_recursions += 1
end while;
true_finishingtime[] = nr_of_recursions - finishingtime[];
DFS:
for each recursion found
dfs_task_stack.push(task_params)
end for;
t++; finishingtime...
Not sure of your algorithm but it may be significant which order you push your tasks to the stack, i.e. the order of "for each ...".
I took the liberty of redefining the meaning of "finishingtime" to its inverse. To get the original definition substract the new finishingtime with the total number of recursions made.
I don't know if this is the best solution but you can build the list of finished times using just a stack and a visited state array, by having more than one visited state.
The following code is just to illustrate the algorithm. I didn't actually tested it a lot (just a little {{0, {1}}, {1, <>}, {2, <>}} small test) but I already used this technique in the very same way in the past for bigger graphs and I know it works.
The idea is to keep the visited node in the stack after it's being visited until all visited before it are pop, thus emulating the recursive call but with less data pushed and in a stack object.
#include <iostream>
#include <vector>
#include <stack>
#include <cassert>
#include <unordered_map>
using namespace std;
typedef enum {
vssClean,
vssPushed,
vssVisited
} VerticeStackState;
typedef unordered_map <int, vector<int>> graph;
void kosarajuBuildFinishOrder(const int inital, graph &G, vector<int> &finish, vector<VerticeStackState> &state, int &lastFinished) {
assert(vssClean == state[inital]);
std::stack<int> stack;
stack.push(inital);
state[inital] = vssPushed;
int current;
while (!stack.empty())
{
current = stack.top();
if (vssPushed == state[current])
{
state[current] = vssVisited;
for (const auto to: G[current])
{
if (state[to]==vssClean)
{
state[to] = vssPushed;
stack.push(to);
}
}
}
else {
assert(vssVisited == state[current]);
stack.pop();
finish[--lastFinished] = current;
}
}
}
int main() {
graph G;
G.insert({0, vector<int>(1, 1)});
G.insert({1, vector<int>()});
G.insert({2, vector<int>()});
vector<int> finish(G.size(), 0);
vector <VerticeStackState> state(G.size(), vssClean);
int lastFinished = G.size();
for (int i=0; i < G.size(); ++i) {
if (vssClean == state[i]){
kosarajuBuildFinishOrder(i, G, finish, state, lastFinished);
}
}
for (auto i: finish) {
cout << i << " ";
}
return 0;
}
For one of the options you mentioned about increasing the stack size, you can do as such:
g++ -Wl,--stack,16777216 -o kosaraju.exe kosaraju_stl.cpp
This increases the stack size to 16MiB. While as mentioned in earlier answers, it's just postponing the problem.
typedef unordered_map <int, vector<int>> graph;
void DFS (graph &G, vector <bool> &visited) {
std::stack<int> stack;
stack.push(0); // root
int i, j;
while(!stack.empty())
{
i = stack.pop_back();
visited[i] = true;
for (j= (int) G[i].size() -1; j >= 0; j--)
{
if (!visited[G[i][j]])
{
stack.push_back(G[i][j]);
}
}
t++;
finishingTime[t] = i; //important step
} // end while.
}
Anyone can make a programming error and since I don't have your test data I can't test this, but is output the same?

Implementing Queue With Two Stacks - Dequeuing Test Issue?

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

C++ Stack Implementation

Hey all! Having a little trouble with my stack. Im trying to print each element that I've pushed onto the stack.
Starting with the stack ctor we know that we have a fixed size for the array. So I allocate the items struct object to hold just that much space:
stack::stack(int capacity)
{
items = new item[capacity];
if ( items == NULL ) {
throw "Cannot Allocoate Sufficient Memmory";
exit(1);
}
maxSize = capacity;
top = -1;
}
Yes, items is a struct type of the object "item". Have a look:
class stack
{
stack(int capacity);
~stack(void);
...
private:
int maxSize; // is for the item stack
int top; // is the top of the stack
struct item {
int n;
};
item *items;
public:
friend ostream& operator<<(ostream& out, stack& q)
...
First and formost we want to add to the stack by pushing each incoming element into the array FILO:
bool stack::pushFront( const int n )
{
if ( top >= maxSize-1 )
{
throw "Stack Full On Push";
return false;
}
else
{
++top;
items[top].n = n;
}
return true;
}
// just a textbook example here:
stack::~stack(void)
{
delete [] items;
items = NULL;
maxSize = 0;
top = -1;
}
Yes the real issue for me is the items[++top].n = n; statement. I've been trying to find out how I can drag (+) the items array out to see ALL of the array elements after I push onto the stack.
Im wondering why I cant drag that items[++top].n = n statement out when im debugging. All that comes up is the value that is passed as an 'n' paramater. Do I need to use a stack object type array to store the values into?
When I overload the << operator and try to print the elements I get an insanely large negative number:
ostream& operator<<(ostream& out, stack& q)
{
if ( q.top <= 0 ) // bad check for empty or full node
out << endl << "stack: empty" << endl << endl;
else
for ( int x = 0; x < q.maxSize; x++ )
{
out << q.items[x].n; // try to print elements
}
return out;
}
I'm way off and I need some guidence if anyone has the time!
In the overloaded << operator in the for loop you are iterating maxsize times. But you might not have pushed maxsize elements into the stack. You should iterate top times. Also, write a default constructor for item structure and initialize all the variblaes so that you do not get garbage values when you try to print them.
When printing the stack, you should only go up to top, not up to maxSize.