c/c++蓝桥杯经典编程题100道(18)括号匹配

括号匹配

->返回c/c++蓝桥杯经典编程题100道-目录


目录

括号匹配

一、题型解释

二、例题问题描述

三、C语言实现

解法1:栈匹配法(难度★)

解法2:计数器法(仅限单一括号类型,难度★☆)

四、C++实现

解法1:使用STL栈(难度★)

解法2:哈希表优化(难度★★)

五、总结对比表

六、特殊方法与内置函数补充

[1. C语言中的动态栈](#1. C语言中的动态栈)

[2. C++的 unordered_map](#2. C++的 unordered_map)

[3. 递归解法(不推荐)](#3. 递归解法(不推荐))


一、题型解释

括号匹配是验证字符串中的括号是否正确闭合的问题。常见题型:

  1. 基础匹配 :验证字符串中的 ()[]{} 是否成对且顺序正确。

  2. 包含其他字符:字符串中混合其他字符(如字母、数字),需跳过非括号字符。

  3. 最长有效括号子串:找到字符串中最长的有效括号子串长度。

  4. 最小添加次数:计算使括号匹配所需最少添加的括号数量。


二、例题问题描述

例题1 :输入 "()[]{}",输出 true(所有括号正确匹配)。
例题2 :输入 "{[()]}",输出 true(嵌套括号正确匹配)。
例题3 :输入 "(]",输出 false(括号类型不匹配)。
例题4 :输入 "()(()",输出最长有效子串长度 2


三、C语言实现

解法1:栈匹配法(难度★)

通俗解释

  • 像叠盘子一样,遇到左括号"放入盘子",遇到右括号时检查最上面的盘子是否匹配。

c

cs 复制代码
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#define MAX_SIZE 10000

bool isValid(char *s) {
    char stack[MAX_SIZE]; // 用数组模拟栈
    int top = -1;         // 栈顶指针
    for (int i = 0; s[i] != '\0'; i++) {
        char c = s[i];
        if (c == '(' || c == '[' || c == '{') { // 左括号入栈
            stack[++top] = c;
        } else { // 右括号检查匹配
            if (top == -1) return false; // 栈为空,无法匹配
            char topChar = stack[top--];
            if ((c == ')' && topChar != '(') || 
                (c == ']' && topChar != '[') || 
                (c == '}' && topChar != '{')) {
                return false;
            }
        }
    }
    return top == -1; // 栈必须为空才完全匹配
}

int main() {
    printf("%d\n", isValid("()[]{}")); // 输出 1(true)
    printf("%d\n", isValid("([)]"));    // 输出 0(false)
    return 0;
}

代码逻辑

  1. 栈初始化 :数组 stack 模拟栈,top 表示栈顶索引。

  2. 遍历字符

    • 左括号:入栈,top 加1。

    • 右括号:若栈为空直接失败;否则弹出栈顶元素检查是否匹配。

  3. 最终检查:遍历结束后栈必须为空,否则存在未闭合的左括号。


解法2:计数器法(仅限单一括号类型,难度★☆)

通俗解释

  • 统计左右括号数量,左括号加1,右括号减1,中途不能为负,最终必须归零(仅适用于单一括号类型,如纯 ())。

c

cs 复制代码
bool isValidSingleType(char *s) {
    int balance = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] == '(') balance++;
        else if (s[i] == ')') balance--;
        if (balance < 0) return false; // 中途右括号过多
    }
    return balance == 0;
}

int main() {
    printf("%d\n", isValidSingleType("(()())")); // 输出 1
    printf("%d\n", isValidSingleType("())"));    // 输出 0
    return 0;
}

代码逻辑

  1. 平衡计数器:遇到左括号加1,右括号减1。

  2. 中途检查:计数器不能为负(右括号比左括号多)。

  3. 最终检查:计数器归零。

  4. 局限性 :无法处理混合括号类型(如 [))。


四、C++实现

解法1:使用STL栈(难度★)

通俗解释

  • 使用C++标准库的 stack 容器,简化栈操作。

cpp

cpp 复制代码
#include <iostream>
#include <stack>
using namespace std;

bool isValid(string s) {
    stack<char> st;
    for (char c : s) {
        if (c == '(' || c == '[' || c == '{') { // 左括号入栈
            st.push(c);
        } else {
            if (st.empty()) return false; // 栈为空,无法匹配
            char topChar = st.top();
            st.pop();
            if ((c == ')' && topChar != '(') || 
                (c == ']' && topChar != '[') || 
                (c == '}' && topChar != '{')) {
                return false;
            }
        }
    }
    return st.empty(); // 栈必须为空
}

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

代码逻辑

  • 与C语言栈方法逻辑相同,但使用 stack<char> 简化栈操作。

解法2:哈希表优化(难度★★)

通俗解释

  • 使用哈希表存储括号对,简化条件判断。

cpp

cpp 复制代码
#include <iostream>
#include <stack>
#include <unordered_map>
using namespace std;

bool isValidHash(string s) {
    stack<char> st;
    unordered_map<char, char> pairs = {
        {')', '('}, {']', '['}, {'}', '{'}
    };
    for (char c : s) {
        if (pairs.find(c) == pairs.end()) { // 左括号入栈
            st.push(c);
        } else { // 右括号检查匹配
            if (st.empty() || st.top() != pairs[c]) return false;
            st.pop();
        }
    }
    return st.empty();
}

int main() {
    cout << isValidHash("()[]{}") << endl; // 输出 true
    return 0;
}

代码逻辑

  1. 哈希表存储映射:键为右括号,值为对应的左括号。

  2. 简化条件判断:遇到右括号时,直接从哈希表取对应的左括号进行比较。


五、总结对比表

方法 时间复杂度 空间复杂度 优点 缺点
栈匹配法 O(n) O(n) 支持所有括号类型 需要额外空间
计数器法 O(n) O(1) 空间高效 仅支持单一括号类型
STL栈 O(n) O(n) 代码简洁 依赖STL库
哈希表优化 O(n) O(n) 代码可读性高 需理解哈希表

六、特殊方法与内置函数补充

1. C语言中的动态栈

  • 实现方式 :使用动态数组 (mallocrealloc) 实现栈,避免固定大小限制。

2. C++的 unordered_map

  • 作用:快速查找键值对,用于括号映射关系。

3. 递归解法(不推荐)

  • 局限性:递归深度与括号嵌套层数相关,可能导致栈溢出。

->返回c/c++蓝桥杯经典编程题100道-目录

相关推荐
水瓶丫头站住1 分钟前
Qt中QTreeWidget的使用
c++·qt
醉翁之意不在酒.max19 分钟前
自制游戏——斗罗大陆
c++·游戏
加油,旭杏28 分钟前
【C++语言】C++入门
开发语言·c++
Golinie39 分钟前
【C++高并发服务器WebServer】-12:TCP详解及实现
服务器·c++·tcp·webserver
小蜗牛~向前冲1 小时前
MFC线程安全案例
c++·mfc
_不会dp不改名_1 小时前
leetcode_80删除有序数组中的重复项 II
数据结构·算法·leetcode
√尖尖角↑1 小时前
力扣——【104. 二叉树的最大深度】
python·算法·leetcode
幸运小圣1 小时前
LeetCode热题100- 轮转数组【JavaScript讲解】
javascript·算法·leetcode
MYX_3091 小时前
第七节 文件与流
开发语言·c++·学习·算法
Lostgreen1 小时前
解密K-means:简单易懂的算法指南
算法·机器学习·kmeans