(顺序栈)有效括号序列

前言:

此篇是针对顺序栈的经典练习题。

问题描述:

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例 1:

输入:s = “()”
输出:true
示例 2:

输入:s = “()[]{}”
输出:true
示例 3:

输入:s = “(]”
输出:false

提示:

① 1 <= s.length <= 104
② s 仅由括号 ‘()[]{}’ 组成

问题解析:

判断括号的有效性可以使用「栈」这一数据结构来解决。

我们遍历给定的字符串 s。当我们遇到一个左括号时,我们会期望在后续的遍历中,有一个相同类型的右括号将其闭合。由于后遇到的左括号要先闭合,因此我们可以将这个左括号放入栈顶。

当我们遇到一个右括号时,我们需要将一个相同类型的左括号闭合。此时,我们可以取出栈顶的左括号并判断它们是否是相同类型的括号。如果不是相同的类型,或者栈中并没有左括号,那么字符串 s 无效,返回 False。为了快速判断括号的类型,我们可以使用哈希表存储每一种括号。哈希表的键为右括号,值为相同类型的左括号。

在遍历结束后,如果栈中没有左括号,说明我们将字符串 s 中的所有左括号闭合,返回 True,否则返回 False。

注意到有效字符串的长度一定为偶数,因此如果字符串的长度为奇数,我们可以直接返回 False,省去后续的遍历判断过程。

代码实现:

char pairs(char a) {//判断括号
    if (a == '}') return '{';
    if (a == ']') return '[';
    if (a == ')') return '(';
    return 0;
}

bool isValid(char* s) {
    int n = strlen(s);//strlen()函数作用 返回字符串中的字符个数
    if (n % 2 == 1) {
        return false;
    }
    int stk[n + 1], top = 0;
    for (int i = 0; i < n; i++) {
        char ch = pairs(s[i]);
        if (ch) {
            if (top == 0 || stk[top - 1] != ch) {
                return false;
            }
            top--;
        } else {
            stk[top++] = s[i];
        }
    }
    return top == 0;
}

总结:

在这里插入图片描述

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
好的,以下是 C 语言顺序栈实现括号匹配的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAXSIZE 100 // 的最大长度 typedef struct { char data[MAXSIZE]; int top; // 顶指针 } Stack; // 初始化 void InitStack(Stack *S) { S->top = -1; } // 判断是否为空 bool IsEmpty(Stack *S) { return S->top == -1; } // 判断是否已满 bool IsFull(Stack *S) { return S->top == MAXSIZE - 1; } // 入 bool Push(Stack *S, char c) { if (IsFull(S)) { return false; } S->data[++S->top] = c; return true; } // 出 bool Pop(Stack *S, char *c) { if (IsEmpty(S)) { return false; } *c = S->data[S->top--]; return true; } // 获取顶元素 bool GetTop(Stack *S, char *c) { if (IsEmpty(S)) { return false; } *c = S->data[S->top]; return true; } // 判断是否为左括号 bool IsLeft(char c) { return c == '(' || c == '[' || c == '{'; } // 判断是否为右括号 bool IsRight(char c) { return c == ')' || c == ']' || c == '}'; } // 判断左右括号是否匹配 bool IsMatch(char left, char right) { return (left == '(' && right == ')') || (left == '[' && right == ']') || (left == '{' && right == '}'); } // 判断括号序列是否匹配 bool IsParenthesesMatch(char *str) { Stack S; InitStack(&S); for (int i = 0; str[i] != '\0'; i++) { if (IsLeft(str[i])) { // 左括号 Push(&S, str[i]); } else if (IsRight(str[i])) { // 右括号顶元素匹配则出 char top; if (!Pop(&S, &top) || !IsMatch(top, str[i])) { return false; } } } // 括号序列匹配当且仅当为空 return IsEmpty(&S); } int main() { char str[MAXSIZE]; printf("请输入括号序列:"); scanf("%s", str); if (IsParenthesesMatch(str)) { printf("括号序列匹配\n"); } else { printf("括号序列不匹配\n"); } return 0; } ``` 代码的思路是:遍历括号序列,若是左括号则入,若是右括号则与顶元素匹配,若匹配则将顶元素出,否则返回不匹配。最后判断是否为空,若为空则括号序列匹配,否则不匹配。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级Mr Yin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值