函数返回堆栈的第二个元素而不改变C ++中的堆栈

时间:2014-04-21 02:00:25

标签: c++ stack

我认为在没有弹出堆栈的情况下返回堆栈的第二个元素的最好方法是创建一个函数是使用peek但是peek返回顶部元素。我如何覆盖peek以便它返回第二个元素,或者以其他方式使用peek来实现我的目标?

5 个答案:

答案 0 :(得分:1)

这就像java算法一样。你要做的是使用一个变量来存储堆栈的顶部(如果它存在则弹出),使用另一个来存储堆栈的第二个元素(如果它存在则查看),将顶部元素推回然后返回第二个元素。

Object obj = stack.empty() ? null : stack.pop();
if(obj == null)
    return null;
Object ret = stack.empty() ? null : stack.peek();
stack.push(obj);
return ret;

但一切都取决于堆栈的实现方式。在C ++中,你必须做这样的事情。

if(stck.size() < 2) throw "Stack has no second element!";
Object obj = stck.top();
stck.pop();
Object ret = stck.top();
stack.push(obj);
return ret

答案 1 :(得分:1)

根据C ++标准std::stack包含名为c的容器的受保护成员变量。知道这一点并使用一点点魔法,您可以使用指向此成员变量的指针来访问它。一旦您有权访问底层容器(默认为std::deque),您就可以访问包含的数据。

template<class T /* value type */, class C /* container */>
typename std::stack<T, C>::container_type& GetContainer(std::stack<T,C>& adapter)
{
    struct AdapterAccessor : std::stack<T, C>
    {
        static std::stack<T, C>::container_type& Get(std::stack<T, C>& adapter)
        {
            return adapter.*&AdapterAccessor::c;
        }
    };

    return AdapterAccessor::Get(adapter);
}

这是有效的,因为尽管AdapterAccessor无法直接访问adapters的内容,但它确实通过指向成员的指针进行间接访问。

您还可以将其与其他容器适配器一起使用。

template <template<class, class> class Adapter, class T, class... Args>
typename Adapter<T, Args...>::container_type&
GetContainer(Adapter<T, Args...>& adapter)
{
    struct AdapterAccessor : Adapter<T, Args...>
    {
        static Adapter<T, Args...>::container_type& Get(Adapter<T, Args...>& adapter)
        {
            return adapter.*&AdapterAccessor::c;
        }
    };

    return AdapterAccessor::Get(adapter);
}

使用示例:

int main()
{
    std::stack<char> st;
    st.push('1');
    st.push('2');
    st.push('3');
    st.push('4');

    auto& contents = GetContainer(st);
    std::cout << contents[0] << std::endl;
    std::cout << contents[3] << std::endl;
    std::cout << contents[1] << std::endl;
    std::cout << contents[2] << std::endl;
}

答案 2 :(得分:0)

我不确定是否可能,因为堆栈基于最后一个原则。你所拥有的只是指向堆栈的指针,从那里你可以从堆栈的顶部弹出,但你不能在堆栈中弹出。我能想到的唯一方法就是创建一个类似的函数。

object returnSecond(stack<object> a){
 a.pop();
 return a.top();
}

或更通用的一个功能,如

object peekN(stack<object> a, int n){
 for(int i = 0;i<n;i++){
  a.pop();
 }
return a.top();
}

答案 3 :(得分:0)

不受限于&#34; Stack&#34;。它是一种抽象数据类型,因此您可以定义自己的数据类型。如果您不想定义数据类型并希望使用堆栈的某些功能。我建议你定义一个自己的功能(就像Sudo Andrew的答案)。但它看起来很牵强,而不像堆栈。

答案 4 :(得分:0)

只需使用std :: vector。

std::vector<int>numbers;

numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);

int secondElem = *(nums.end() - 2);

cout << secondElem << endl;

打印2