潘师傅频道,拒绝粗制滥造,只做精品之:数据结构练习题:栈在括号匹配中的应用

栈在括号匹配中的应用

目标:用栈来实现对括号序列串的匹配

tips:栈是一种操作受限的线性表,只允许在线性表的某一端进行增删操作,且遵循后进先出原则(LIFO)

简述步骤:

首先要对字符串进行逐个扫描,若扫描到的符号为左括号(‘(’||‘{’||‘【’)则压入栈顶若为右括号(‘)’||‘}’||‘】’),则弹出栈顶元素并赋值给字符类变量,然后进行判断,若弹出的栈顶元素刚好与扫描到的右括号相互匹配,则继续向下进行扫描,若不匹配则返回FALSE。当栈空且还有未匹配的右括号时返回FALSE,当栈未空但字符串还有残余的右括号时返回FALSE,当栈空且字符串扫描完毕时返回TRUE。

需要具备的基础知识:栈的基本操作

相关基本操作的代码实现:

  1. 栈的结构体定义(此处采用的方法为创建顺序栈,也可以使用链栈来实现相关操作)

typedef struct {
    char data[MaxSize];//采用数组的形式来存放栈
    int top;//定义栈顶指针
} SqStack;
  1. 栈的初始化

void InitSqStack(SqStack &S) {
    S.top = -1;//栈顶初始化为-1
}
  1. 压栈,出栈

bool Push(SqStack &S, char x) { //需要注意,插入元素的位置应该是在栈的下一个空位中,因此栈顶指针要先加1后在进行传值操作
    if (S.top == MaxSize - 1)
        return false;
    S.top = S.top + 1;
    S.data[S.top] = x; //博主的血泪教训:特别注意,代码的运算逻辑是先右再左,一定是x赋值给栈顶元素,左右顺序不能弄反
    return true;
}

bool Pop(SqStack &S, char &x) { //先用x将栈顶元素带出,再改变指针所指向的位置{
    if (S.top == -1)
        return false;
    x = S.data[S.top];
    S.top = S.top - 1;
    return true;
}
  1. 栈的判空

bool StackEmpty(SqStack S) {
    if (S.top == -1)
        return true;
    else
        return false;
}

功能模块代码逻辑:

①循环扫描数组内的每一个元素,判断是否为若为左括号则压入栈顶

②若不是左括号,判断栈是否未空,若为空,返回失败,若不为空,则弹出栈顶元素,此时可知当前扫描到的元素一定为右括号

③判断栈顶元素是否和当前扫描到的右括号相匹配,若匹配,则继续扫描下一个元素,若不匹配,则返回失败

④若扫描到右括号但栈空,则返回失败,若扫描结束但栈不为空,则返回失败

⑤若扫描结束同时判断栈为空,则代表匹配成功,返回成功

功能模块的代码实现:

bool bracketcheck(char str[], int length) {
    SqStack S;
    InitSqStack(S);
    for (int i = 0; i < length; i++) {
        if (str[i] == '(' || str[i] == '[' || str[i] == '{')
            Push(S, str[i]);
        else {
            if (StackEmpty(S))
                return false;
            char topElem;
            Pop(S, topElem);
            if (str[i] == ')' && topElem != '(')
                return false;
            if (str[i] == '}' && topElem != '{')
                return false;
            if (str[i] == ']' && topElem != '[')
                return false;
        }
    }
    return StackEmpty(S);
}

汇总:


#define MaxSize 10
#include <stdio.h>

typedef struct {
    char data[MaxSize];
    int top;
} SqStack;

void InitSqStack(SqStack &S) {
    S.top = -1;
}

bool StackEmpty(SqStack S) {
    if (S.top == -1)
        return true;
    else
        return false;
}

bool Push(SqStack &S, char x) { //需要注意,插入元素的位置应该是在栈的下一个空位中,因此栈顶指针要先加1后在进行传值操作
    if (S.top == MaxSize - 1)
        return false;
    S.top = S.top + 1;
    S.data[S.top] = x; //博主的血泪教训:特别注意,代码的运算逻辑是先右再左,一定是x赋值给栈顶元素,左右顺序不能弄反
    return true;
}

bool Pop(SqStack &S, char &x) { //先用x将栈顶元素带出,再改变指针所指向的位置{
    if (S.top == -1)
        return false;
    x = S.data[S.top];
    S.top = S.top - 1;
    return true;
}

bool bracketcheck(char str[], int length) {
    SqStack S;
    InitSqStack(S);
    for (int i = 0; i < length; i++) {
        if (str[i] == '(' || str[i] == '[' || str[i] == '{')
            Push(S, str[i]);
        else {
            if (StackEmpty(S))
                return false;
            char topElem;
            Pop(S, topElem);
            if (str[i] == ')' && topElem != '(')
                return false;
            if (str[i] == '}' && topElem != '{')
                return false;
            if (str[i] == ']' && topElem != '[')
                return false;
        }
    }
    return StackEmpty(S);//此处判断栈是否为空,若为空,则匹配成功,若不未空,则代表检测到还有剩余的左括号,匹配失败
}
int main() {
    int n;
    printf("请输入想要传入字符串的长度\n");
    scanf("%d\n", &n);//此处一定要加入\n,否则末尾自动占用一个字符的空间
    char a[n];
    for (int i = 0; i < n; i++) {
        scanf("%C", &a[i]);
    }
    if (bracketcheck(a, n))
        printf("字符串匹配");
    else
        printf("字符串不匹配");
    return 0;
}

代码测试结果截图:

1

2

3

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一臭打代码的 aka 潘先生です

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

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

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

打赏作者

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

抵扣说明:

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

余额充值