halostack
halostack

Reputation: 1093

How to direct access to the elements of stack in C++?

For some reason, I have to use a stack to achieve some function, but I need to reverse the output stack's elements. So I want to use stack<char,vector<char> to achieve direct access, but there may be some error in my suggestion. Can anyone tell me how to efficiently reverse the output stack's elements in C++ using STL stack?

Upvotes: 0

Views: 5567

Answers (5)

Richard
Richard

Reputation: 61259

In general you should not do this.

It's inappropriate to choose a container which is specifically designed to limit your access to its contents and then say that you really do want that access.

It's preferable to choose a container that's built to meet your needs. In this case using a deque seems more appropriate.

But, if you reeaaaaallllyyyy want to do something kind of stupid, this is how you'd access the members of the stack directly (note that this does not use gobs of extra memory and time to build a temporary reverse stack, as some of the other answers have suggested):

#include <stack>
#include <deque>
#include <cstdlib>
#include <iostream>
using namespace std;

template <class T, class S>
    S& Container(stack<T, S>& q) {
        struct HackedStack : private stack<T, S> {
            static S& Container(stack<T, S>& q) {
                return q.*&HackedStack::c;
            }
        };
    return HackedStack::Container(q);
}

int main()
{
    stack<int> st;
    deque<int> &mems = Container(st);

    cout<<"Putting numbers into the stack"<<endl;
    for(int i=0;i<20;i++){
        int temp=rand();
        cout<<temp<<endl;
        st.push(rand());
    }

    cout<<endl<<"Reading numbers in the stack"<<endl;
    for(deque<int>::iterator i=mems.begin();i!=mems.end();i++)
        cout<<*i<<endl;

    cout<<endl<<"Taking numbers out of the stack"<<endl;
    while(!st.empty()){
        int temp=st.top();
        st.pop();
        cout<<temp<<endl;
    }

    return 0;
}

And, yes, if you change all of the deque references to vector references, this will still work fine. But deque is probably the preferable container to use with your stack.

Upvotes: 0

Kos
Kos

Reputation: 72241

If you want to access the elements in any order, why use a stack in the first place?

Use std::vector or std::deque directly, then iterate backwards like

for (auto iter = vec.rbegin(); iter != vec.rend(); ++iter) {
    process(*iter);
}

If you really need to, there's a hackish-but-correct way to access the stack's underlying container object.

See: how to print out all elements in a std::stack or std::queue conveniently

Upvotes: 1

BigBoss
BigBoss

Reputation: 6914

If you don't want to or you can't use stack in desired way, first you should think that do you really need stack? for example it might be better to use queue or deque in place of stack, so you can control it better!

Upvotes: 1

evanmcdonnal
evanmcdonnal

Reputation: 48076

To reverse the output use this simple recursive function (pseudo code)

  void recursiveWalk(Node* current)
  {
       if (current->next != NULL)
           recusiveWalk(current->next);
        // do stuff here
  }

  //call passing top
  recursiveWalk(stack->top);

This will build up the stack in reverse order. When you're on the last element the call stack will start to unwind allowing you to operate on the stack from bottom to top.

Upvotes: -1

john
john

Reputation: 87959

Use a temporary stack.

// On exit the stack 's' will have it's elements reversed.
void reverse_stack(std::stack<int>& s)
{
    std::stack<int> tmp;
    while (!s.empty())
    {
        tmp.push(s.pop());
    }
    s.swap(tmp);
}

Upvotes: 3

Related Questions