0
点赞
收藏
分享

微信扫一扫

Flink CEP(二) 运行源码解析

绪风 2023-07-30 阅读 89

📖 1.1 什么是栈

栈是一种线性数据结构,具有后进先出(Last-In-First-Out,LIFO)的特点。可以类比为装满盘子的餐桌,每次放盘子都放在最上面,取盘子时也从最上面取,因此最后放进去的盘子最先取出。栈的典型应用场景有函数调用、括号匹配、表达式求值等。

元素从固定一侧开口进入和离开栈的操作,分别称为入栈和出栈。

栈中元素由深到浅存储,我们将栈最深的存储位置称为栈底,当前栈中最外围元素所在的位置则称为栈顶。

在这里插入图片描述

栈底通常固定不变,而栈顶则由当前栈中最外侧元素位置(栈中元素数量)确定。

由栈的特点可知栈的插入和删除(入栈和出栈)操作都是在栈顶这一端进行的。

栈顶(Top):线性表允许进行插入删除的那一端。
栈底(Bottom):固定的,不允许进行插入和删除的另一端。
空栈:不含任何元素的空表。

栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构

💻 1.2 栈的实现(数组模拟)

栈的实现可以使用数组来模拟。我们可以定义一个固定大小的数组和一个指向栈顶的指针。栈顶指针初始化为 -1,表示栈为空。每次入栈操作时,将元素放入数组并将栈顶指针加一;出栈操作时,将栈顶指针减一。

#include <iostream>
using namespace std;

const int MAX_SIZE = 100; // 栈的最大容量
int stack[MAX_SIZE]; // 栈的数组
int top = -1; // 栈顶指针

// 入栈操作
void push(int x) {
    if (top >= MAX_SIZE - 1) {
        cout << "栈已满,无法入栈!" << endl;
        return;
    }
    stack[++top] = x;
}

// 出栈操作
void pop() {
    if (top == -1) {
        cout << "栈为空,无法出栈!" << endl;
        return;
    }
    top--;
}

// 获取栈顶元素
int peek() {
    if (top == -1) {
        cout << "栈为空,无栈顶元素!" << endl;
        return -1;
    }
    return stack[top];
}

// 判断栈是否为空
bool isEmpty() {
    return top == -1;
}

// 获取栈的大小
int size() {
    return top + 1;
}

int main() {
    push(1);
    push(2);
    push(3);
    
    cout << "当前栈顶元素:" << peek() << endl;
    cout << "栈的大小:" << size() << endl;
    
    pop();
    cout << "当前栈顶元素:" << peek() << endl;
    cout << "栈是否为空:" << (isEmpty() ? "是" : "否") << endl;
    
    return 0;
}

运行结果:

当前栈顶元素:3
栈的大小:3
当前栈顶元素:2
栈是否为空:否

📚 1.3 栈的实现(STL 方法)

在 C++ 中,我们也可以使用标准模板库(STL)提供的 stack 容器来实现栈。使用 stack 容器非常方便,不需要手动处理数组和指针。

#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> st;
    
    st.push(1);
    st.push(2);
    st.push(3);
    
    cout << "当前栈顶元素:" << st.top() << endl;
    cout << "栈的大小:" << st.size() << endl;
    
    st.pop();
    cout << "当前栈顶元素:" << st.top() << endl;
    cout << "栈是否为空:" << (st.empty() ? "是" : "否") << endl;
    
    return 0;
}

运行结果:

当前栈顶元素:3
栈的大小:3
当前栈顶元素:2
栈是否为空:否

使用 stack 容器,我们可以更方便地实现栈的入栈、出栈、获取栈顶元素等操作,而无需自己处理底层的数据结构。

🚂 1.4 出入栈顺序(火车调度案例)

火车调度是一个经典的栈的应用场景。给定 n 辆火车的进站顺序,请输出所有可能的出站顺序。

我们使用递归来生成所有可能的出站顺序。对于每一辆火车,它可以先进站再出站,也可以直接从进站过程中出站。我们不断尝试所有可能的出站顺序,直到所有火车都出站。

#include <iostream>
#include <vector>
using namespace std;

void dfs(vector<int>& in, vector<int>& out, vector<int>& path) {
    if (in.empty() && out.empty()) {
        for (int num : path) {
            cout << num << " ";
        }
        cout << endl;
        return;
    }
    
    if (!in.empty()) {
        int num = in.back();
        in.pop_back();
        path.push_back(num);
        dfs(in, out, path);
        path.pop_back();
        in.push_back(num);
    }
    
    if (!out.empty()) {
        int num = out.back();
        out.pop_back();
        path.push_back(num);
        dfs(in, out, path);
        path.pop_back();
        out.push_back(num);
    }
}

int main() {
    vector<int> in = {1, 2, 3};
    vector<int> out;
    vector<int> path;
    dfs(in, out, path);
    
    return 0;
}

运行结果:

1 2 3 
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

🧩 1.5 栈的应用

有效的括号

题目描述

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = "()"
输出:true

示例 2:

输入:s = "()[]{}"
输出:true

示例 3:

输入:s = "(]"
输出:false

提示:

  • 1 <= s.length <= 104
  • s 仅由括号 '()[]{}' 组成

栈在括号匹配中有着重要的应用。给定一个只包含 ()[]{} 的字符串,判断括号是否匹配。

使用栈可以轻松解决这个问题。遍历字符串中的每个字符,如果是左括号,将其入栈;如果是右括号,判断与栈顶元素是否匹配,若匹配则出

栈,否则返回 false。最后检查栈是否为空,为空则括号匹配。

#include <iostream>
#include <stack>
#include <unordered_map>
using namespace std;

bool isValid(string s) {
    stack<char> st;
    unordered_map<char, char> mapping = {{')', '('}, {']', '['}, {'}', '{'}};
    
    for (char c : s) {
        if (c == '(' || c == '[' || c == '{') {
            st.push(c);
        } else if (c == ')' || c == ']' || c == '}') {
            if (st.empty() || st.top() != mapping[c]) {
                return false;
            }
            st.pop();
        }
    }
    
    return st.empty();
}

int main() {
    cout << isValid("()") << endl;         // 输出:1 (true)
    cout << isValid("()[]{}") << endl;     // 输出:1 (true)
    cout << isValid("(]") << endl;         // 输出:0 (false)
    
    return 0;
}

在这里插入图片描述

在这里插入图片描述

📝 总结

栈是一种非常重要的数据结构,在计算机算法中有着广泛的应用。通过模拟入栈和出栈操作,我们可以解决很多实际问题,比如火车调度、括号匹配等。同时,C++ 中也提供了标准模板库(STL)中的 stack 容器,方便我们使用栈来解决问题。熟练掌握栈的使用将会对你的编程技能有很大的提升。

⭐️希望本篇文章对你有所帮助。

⭐️如果你有任何问题或疑惑,请随时向提问。

⭐️感谢阅读!

举报

相关推荐

0 条评论