【041】从零开始:逐步学习使用C++ STL中的stack容器

从零开始:逐步学习使用C++ STL中的stack容器

  • 引言
  • 一、stack容器概述
  • 二、stack容器常用API
    • 2.1、构造函数
    • 2.2、赋值操作
    • 2.3、数据存取操作
    • 2.4、大小操作
  • 三、使用stack容器实现一个高效的算法
  • 总结

引言


作者简介:一个热爱分享高性能服务器后台开发知识的博主,目标是通过理论与代码实践的结合,让世界上看似难以掌握的技术变得易于理解与掌握。技能涵盖了多个领域,包括C/C++、Linux、Nginx、MySQL、Redis、fastdfs、kafka、Docker、TCP/IP、协程、DPDK等。

️ CSDN实力新星、CSDN博客专家

专栏介绍:从零到c++精通的学习之路。内容包括C++基础编程、中级编程、高级编程;掌握各个知识点。

专栏地址:C++从零开始到精通

博客主页:https://blog.csdn.net/Long_xu


上一篇:【040】巧妙地穿梭双端:掌握C++ STL中deque容器的强大功能

一、stack容器概述

stack是一种先进后出(First In Last OutFILO)的数据结构,它只有一个出口,形式如图所示。stack容器允许新增元素,移除元素,取得栈顶元素,但是除了最顶端外,没有任何其他方法可以存取stack的其他元素。换言之,stack不允许有遍历行为。有元素入栈的操作称为:push,将元素推出stack 的操作称为pop。
【041】从零开始:逐步学习使用C++ STL中的stack容器_第1张图片
Stack所有元素的进出都必须符合"先进后出"的条件,只有stack顶端的元素,才有机会被外界取用。Stack不提供遍历功能,也不提供迭代器。

二、stack容器常用API

C++的stack容器是通过头文件提供的。

  1. 构造函数:

    • stack s:创建一个空的stack,其中T是数据类型。
  2. 成员函数:

    • push(const T& val):将元素val压入栈顶。
    • emplace(Args&&... args):通过参数构造一个元素并将其压入栈顶。
    • pop():移除栈顶元素。
    • top():返回栈顶元素的引用。
    • empty():检查栈是否为空,返回布尔值。
    • size():返回栈中元素的个数。
  3. 非成员函数:

    • swap(stack& other):交换两个栈的内容。

stack不提供遍历功能,因为它是一种后进先出(LIFO)数据结构。

2.1、构造函数

stack容器的构造函数原型如下:

explicit stack(const Container& cont = Container());

其中,Container是可选参数,用于指定底层容器类型,默认为deque

以下是几个使用示例:

示例 1:使用默认构造函数创建空的stack

#include 
#include 

int main() {
    std::stack<int> s; // 默认构造函数创建一个空的stack

    if (s.empty()) {
        std::cout << "Stack is empty!" << std::endl;
    }

    return 0;
}

示例 2:使用vector作为底层容器创建stack

#include 
#include 
#include 

int main() {
    std::stack<int, std::vector<int>> s; // 使用vector作为底层容器

    s.push(10);
    s.push(20);
    s.push(30);

    while (!s.empty()) {
        std::cout << s.top() << " "; // 输出栈顶元素
        s.pop(); // 弹出栈顶元素
    }
    
    return 0;
}

示例 3:使用现有容器初始化stack

#include 
#include 
#include 

int main() {
    std::list<int> values = {1, 2, 3, 4};

    std::stack<int, std::list<int>> s(values); // 使用现有容器初始化stack

    while (!s.empty()) {
        std::cout << s.top() << " "; // 输出栈顶元素
        s.pop(); // 弹出栈顶元素
    }

    return 0;
}

这些示例展示了如何使用stack容器的构造函数来创建空的栈或从现有容器初始化栈。可以根据需要选择不同的底层容器类型,如默认的deque或用户指定的vectorlist等。

2.2、赋值操作

可以使用std::stack模板类中的成员函数swap()来交换两个栈的内容实现赋值的效果。

swap()函数的原型如下:

void swap(stack& other);

使用示例:

#include 
#include 

int main() {
    std::stack<int> stack1;
    std::stack<int> stack2;

    stack1.push(1);
    stack1.push(2);
    stack1.push(3);

    stack2.push(4);
    stack2.push(5);

    std::cout << "Stack 1: ";
    while (!stack1.empty()) {
        std::cout << stack1.top() << " "; // 输出栈1的元素
        stack1.pop();
    }
    
    std::cout << "\nStack 2: ";
    while (!stack2.empty()) {
        std::cout << stack2.top() << " "; // 输出栈2的元素
        stack2.pop();
    }

    stack1.swap(stack2); // 交换栈1和栈2的内容

    std::cout << "\nStack 1 after swapping: ";
    while (!stack1.empty()) {
        std::cout << stack1.top() << " "; // 输出交换后的栈1的元素
        stack1.pop();
    }

    std::cout << "\nStack 2 after swapping: ";
    while (!stack2.empty()) {
        std::cout << stack2.top() << " "; // 输出交换后的栈2的元素
        stack2.pop();
    }

    return 0;
}

输出:

Stack 1: 3 2 1 
Stack 2: 5 4 
Stack 1 after swapping: 5 4 
Stack 2 after swapping: 3 2 1 

以上示例中,通过调用swap()函数来交换了两个栈stack1stack2的内容。这样就实现了将一个栈的元素赋值给另一个栈的效果。

2.3、数据存取操作

std::stack容器的数据存取操作函数包括:

  • top():返回栈顶元素的引用,但不会删除该元素。
  • push(const T& value):将元素插入到栈顶。
  • pop():移除栈顶元素,没有返回值。

使用示例:

#include 
#include 

int main() {
    std::stack<int> stack;

    stack.push(1);
    stack.push(2);
    stack.push(3);

    // 访问栈顶元素
    int topElement = stack.top();
    std::cout << "Top element: " << topElement << std::endl;

    // 修改栈顶元素
    stack.top() = 4;

    // 移除栈顶元素
    stack.pop();

    std::cout << "Stack elements:";
    while (!stack.empty()) {
        std::cout << " " << stack.top();
        stack.pop();
    }
    std::cout << std::endl;

    return 0;
}

输出:

Top element: 3
Stack elements: 2 1

2.4、大小操作

std::stack容器提供了以下函数来进行大小操作:

  • empty():返回栈是否为空,如果栈为空则返回true,否则返回false
  • size():返回栈中元素的数量。

以下是这些函数的函数原型和使用示例:

#include 
#include 

int main() {
    std::stack<int> stack;

    stack.push(1);
    stack.push(2);
    stack.push(3);

    bool isEmpty = stack.empty();
    std::cout << "Is stack empty? " << (isEmpty ? "Yes" : "No") << std::endl;

    size_t stackSize = stack.size();
    std::cout << "Stack size: " << stackSize << std::endl;

    return 0;
}

输出:

Is stack empty? No
Stack size: 3

三、使用stack容器实现一个高效的算法

使用C++的stack容器实现简单算法,该算法用于判断一个字符串中的括号是否匹配。

#include 
#include 
#include 

bool isBracketMatching(const std::string& str) {
    std::stack<char> brackets;

    for (char ch : str) {
        if (ch == '(' || ch == '[' || ch == '{') {
            brackets.push(ch);
        } else if (ch == ')' || ch == ']' || ch == '}') {
            // 如果当前字符为右括号
            if (brackets.empty()) {
                // 栈为空,无法匹配
                return false;
            } else {
                char top = brackets.top();
                brackets.pop();

                // 判断栈顶元素与当前右括号是否匹配
                if ((top == '(' && ch != ')') ||
                    (top == '[' && ch != ']') ||
                    (top == '{' && ch != '}')) {
                    return false;
                }
            }
        }
    }

    // 所有字符遍历完成后,栈为空才说明括号全部匹配
    return brackets.empty();
}

int main() {
    std::string str1 = "({})[]"; // 匹配
    std::string str2 = "{[}]";   // 不匹配

    std::cout << "字符串1括号" << (isBracketMatching(str1) ? "匹配" : "不匹配") << std::endl;
    std::cout << "字符串2括号" << (isBracketMatching(str2) ? "匹配" : "不匹配") << std::endl;

    return 0;
}

首先,我们遍历字符串中的每个字符,如果遇到左括号('(''[''{'),我们将其压入栈中。当遇到右括号时,我们检查栈顶元素是否与当前右括号匹配,并将栈顶元素弹出。如果任何时刻栈为空、栈顶元素与当前右括号不匹配,或者遍历结束后栈仍然非空,那么就意味着括号不匹配。

main()函数中,我们测试了两个字符串的括号匹配情况,并输出相应的结果。

运行上述代码,输出:

字符串1括号匹配
字符串2括号不匹配

示例演示了如何利用C++的stack容器来实现一个简单算法,通过使用栈来追踪括号的嵌套关系,并判断括号是否匹配。这只是stack容器的一个简单应用示例,而stack还有其他更多有用的功能可以探索和利用。

总结

深入讲解了C++ STL中的stack容器的基本概念和操作。首先介绍了栈的定义和特点,然后详细解释了stack容器的创建和管理方法,包括入栈、出栈和访问栈顶元素等操作。此外,还重点探讨了stack容器的大小操作函数,并通过实例加深了对其用法的理解。通过本文的学习,读者能够全面了解如何在C++中运用stack来实现栈结构,并且能够合理地利用stack提高代码效率和可读性。无论读者是初学者还是有一定经验的开发者,本文都能帮助他们掌握使用C++ STL中的stack容器的技巧和技能,为日后的编程工作打下坚实的基础。

【041】从零开始:逐步学习使用C++ STL中的stack容器_第2张图片

你可能感兴趣的:(C++从零开始到精通,学习,c++,开发语言,stl,算法,openstack,数据结构)