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

从零开始:逐步学习使用C++ STL中的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。

Stack所有元素的进出都必须符合"先进后出"的条件,只有stack顶端的元素,才有机会被外界取用。Stack不提供遍历功能,也不提供迭代器。

二、stack容器常用API

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

  1. 构造函数:

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

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

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

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

2.1、构造函数

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

cpp 复制代码
explicit stack(const Container& cont = Container());

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

以下是几个使用示例:

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

cpp 复制代码
#include <iostream>
#include <stack>

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

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

    return 0;
}

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

cpp 复制代码
#include <iostream>
#include <stack>
#include <vector>

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

cpp 复制代码
#include <iostream>
#include <stack>
#include <list>

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()函数的原型如下:

cpp 复制代码
void swap(stack& other);

使用示例:

cpp 复制代码
#include <iostream>
#include <stack>

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

输出:

bash 复制代码
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():移除栈顶元素,没有返回值。

使用示例:

cpp 复制代码
#include <iostream>
#include <stack>

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

输出:

bash 复制代码
Top element: 3
Stack elements: 2 1

2.4、大小操作

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

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

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

cpp 复制代码
#include <iostream>
#include <stack>

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

输出:

bash 复制代码
Is stack empty? No
Stack size: 3

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

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

cpp 复制代码
#include <iostream>
#include <stack>
#include <string>

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()函数中,我们测试了两个字符串的括号匹配情况,并输出相应的结果。

运行上述代码,输出:

bash 复制代码
字符串1括号匹配
字符串2括号不匹配

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

总结

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

相关推荐
Crossoads13 分钟前
【数据结构】排序算法---桶排序
c语言·开发语言·数据结构·算法·排序算法
小游鱼KF14 分钟前
Spring学习前置知识
java·学习·spring
扎克begod18 分钟前
JAVA并发编程系列(9)CyclicBarrier循环屏障原理分析
java·开发语言·python
自身就是太阳21 分钟前
2024蓝桥杯省B好题分析
算法·职场和发展·蓝桥杯
code bean26 分钟前
【C#基础】函数传参大总结
服务器·开发语言·c#
阳光阿盖尔36 分钟前
EasyExcel的基本使用——Java导入Excel数据
java·开发语言·excel
蔚一38 分钟前
Java设计模式—面向对象设计原则(三) -----> 依赖倒转原则DIP(完整详解,附有代码+案例)
java·开发语言·设计模式·intellij-idea·依赖倒置原则
liang899943 分钟前
SpringSecurity原理解析(七):权限校验流程
java·开发语言
mez_Blog43 分钟前
个人小结(2.0)
前端·javascript·vue.js·学习·typescript
LQS202044 分钟前
基于Python实现一个浪漫烟花秀
开发语言·python