c++11 标准模板(STL)(std::stack)(四)

定义于头文件 <stack>
template<

    class T,
    class Container = std::deque<T>

> class stack;

 std::stack 类是容器适配器,它给予程序员栈的功能——特别是 FILO (先进后出)数据结构。

该类模板表现为底层容器的包装器——只提供特定函数集合。栈从被称作栈顶的容器尾部推弹元素。

元素访问

访问栈顶元素

std::stack<T,Container>::top

reference top();

const_reference top() const;

 返回 stack 中顶元素的引用。它是最近推入的元素。此元素将在调用 pop() 时被移除。等效于调用 c.back() 。

参数

(无)

返回值

到末尾元素的引用

复杂度

常数

修改器

向栈顶插入元素

std::stack<T,Container>::push

void push( const value_type& value );

void push( value_type&& value );

(C++11 起)

 推给定的元素 value 到 stack 顶。

1) 等效地调用 c.push_back(value)

2) 等效地调用 c.push_back(std::move(value))

参数

value - 要推入的元素值

返回值

(无)

复杂度

等于 Container::push_back 的复杂度。

于顶原位构造元素

std::stack<T,Container>::emplace

template< class... Args >
void emplace( Args&&... args );

(C++11 起)
(C++17 前)

template< class... Args >
decltype(auto) emplace( Args&&... args );

(C++17 起)

推入新元素到 stack 顶。原位构造元素,即不进行移动或复制操作。以与提供给函数者准确相同的参数调用元素的构造函数。

等效地调用 c.emplace_back(std::forward<Args>(args)...); 。

参数

args - 转发给元素构造函数的参数

返回值

(无) (C++17 前)
上述对 Container::emplace_back 的调用返回的值或引用,若它存在。 (C++17 起)

复杂度

等同于 Container::emplace_back 的复杂度。

删除栈顶元素

std::stack<T,Container>::pop

void pop();

从 stack 移除顶元素。等效地调用 c.pop_back() 。

参数

(无)

返回值

(无)

复杂度

等于 Container::pop_back 的复杂度。

交换内容

std::stack<T,Container>::swap

void swap( stack& other ) noexcept(/* see below */);

(C++11 起)

交换容器适配器与 other 的内容。等效地调用 using std::swap; swap(c, other.c); 。

参数

other - 要交换内容的容器适配器

返回值

(无)

示例

noexcept 规定:  

noexcept(noexcept(swap(c, other.c)))

上述表达式中,用与 C++17 std::is_nothrow_swappable 特性所用的相同方式查找标识符 swap

(C++17 前)
noexcept 规定:  

noexcept(std::is_nothrow_swappable<Container>::value)

(C++17 起)

复杂度

与底层容器相同(典型地为常数)。

调用示例

#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <stack>
#include <deque>
#include <time.h>

using namespace std;

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}

    Cell &operator +=(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator +(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator *(const Cell &cell)
    {
        x *= cell.x;
        y *= cell.y;
        return *this;
    }

    Cell &operator ++()
    {
        x += 1;
        y += 1;
        return *this;
    }


    bool operator <(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y < cell.y;
        }
        else
        {
            return x < cell.x;
        }
    }

    bool operator >(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y > cell.y;
        }
        else
        {
            return x > cell.x;
        }
    }

    bool operator ==(const Cell &cell) const
    {
        return x == cell.x && y == cell.y;
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

void stackPrint(const std::string &name, std::stack<Cell> &stack)
{
    std::cout << name ;
    while (stack.size() > 0)
    {
        std::cout << stack.top() << " ";
        stack.pop();
    }
    std::cout << std::endl;
}

int main()
{
    std::cout << std::boolalpha;

    std::mt19937 g{std::random_device{}()};
    srand((unsigned)time(NULL));

    auto generate = []()
    {
        int n = std::rand() % 10 + 110;
        Cell cell{n, n};
        return cell;
    };

    std::deque<Cell> deque1(6);
    std::generate(deque1.begin(), deque1.end(), generate);
    std::cout << "deque1:   ";
    std::copy(deque1.begin(), deque1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    //2) 以 cont 的内容复制构造底层容器 c 。
    std::stack<Cell> stack1(deque1);

    while (!stack1.empty())
    {
        //返回 stack 中顶元素的引用。它是最近推入的元素。
        //此元素将在调用 pop() 时被移除。等效于调用 c.back() 。
        //const_reference
        std::cout << "stack1.top() before: " << stack1.top() << " ";
        //reference
        stack1.top() = generate();
        std::cout << "after: " << stack1.top();
        //从 stack 移除顶元素。等效地调用 c.pop_back()
        stack1.pop();
        std::cout << std::endl;
    }
    std::cout << std::endl;

    std::stack<Cell> stack2;
    while (stack2.size() < 6)
    {
        Cell cell = generate();
        if (stack2.size() % 2 == 0)
        {
            //推给定的元素 value 到 stack 顶。
            //1) 等效地调用 c.push_back(value)
            stack2.push(cell);
        }
        else
        {
            //推给定的元素 value 到 stack 顶。
            //2) 等效地调用 c.push_back(std::move(value)),移动语义
            stack2.push(std::move(cell));
        }
        std::cout << "stack2.top() : " << stack2.top() ;
        std::cout << std::endl;
    }
    std::cout << std::endl;

    std::stack<Cell> stack3;
    while (stack3.size() < 6)
    {
        int n = std::rand() % 10 + 110;
        //推入新元素到 stack 顶。原位构造元素,即不进行移动或复制操作。
        //以与提供给函数者准确相同的参数调用元素的构造函数。
        //等效地调用 c.emplace_back(std::forward<Args>(args)...);
        stack3.emplace(n, n);
        std::cout << "stack3.top() : " << stack3.top() ;
        std::cout << std::endl;
    }
    std::cout << std::endl;

    //交换容器适配器与 other 的内容。
    //等效地调用 using std::swap; swap(c, other.c);
    stack2.swap(stack3);
    stackPrint("stack2:   ", stack2);
    stackPrint("stack3:   ", stack3);

    return 0;
}

输出

猜你喜欢

转载自blog.csdn.net/qq_40788199/article/details/130040368
今日推荐