繁体   English   中英

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

[英]function that returns second element of a stack without altering the stack in C++

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

这是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

根据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;
}

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

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

不限制在“堆栈”中。 它是一种抽象数据类型,因此您可以定义自己的数据类型。 如果您只是不想定义数据类型并希望使用堆栈的某些功能。 我建议你定义一个自己的功能(就像Sudo Andrew的答案)。 但它似乎很牵强,而不是像堆栈。

只需使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM