簡體   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