Application of stack in bracket matching (pure C implementation of stack/chain stack)

Table of contents

1 Problem Background

2 specific ideas

3 code implementation

3.1 Sequential stack implementation

3.2 Chain stack implementation


1 Problem Background

  The parenthesis matching problem of the stack refers to judging whether the parentheses can be matched correctly after a given string (contains various kinds of parentheses), that is, whether each left parenthesis has a corresponding right parenthesis to match it, and the left and right parentheses must start with correct order to match.

For example, the parentheses in the string "((()))" are matched correctly, but the parentheses in the string "()())" are not.

 

2 specific ideas

This is the flowchart given by Wang Dao:

Figure 1 Flowchart given by Wang Dao

 

It seems a bit difficult, let me summarize, it is very simple, just a few steps:

  1. Traverse the given string and judge each character.
  2. If the character is an opening parenthesis, push it onto the stack.
  3. If the character is a closing parenthesis, compare it to the top element of the stack to see if that element is a matching opening parenthesis. If it is, pop the top element of the stack and continue traversing; if not, it means that the brackets do not match, and return false.
  4. If the string is traversed and the stack is empty, it means that all the brackets match, and return true; otherwise, return false.

Note that if the stack is found to be empty when the element is ready to be popped, it means that there is no opening bracket matching the closing bracket, and false is returned.

3 code implementation

Take the last sample question from Acwing as an example: 3693. Bracket Matching - AcWing Question Bank

input format

A total of one line, containing a string consisting of `<`,`(`,`{`,`[`,`>`,`)`,`}`,`]`.

output format

Output `yes` if the parentheses in the input string match correctly, otherwise output `no`.

data range

The length of the input string does not exceed 10000.

Input sample:

    (){}

Sample output:

    yes

 

3.1 Sequential stack implementation

#include<stdio.h>
#include<string.h>
#include<stdbool.h>    //C语言引入该库才有bool值

#define MAX_SIZE 100000  //定义栈中元素的最大个数

typedef struct {
    int data[MAX_SIZE];  //静态数组存放栈中元素
    int top;    //栈顶指针
} SqStack;

//初始化栈
void initStack(SqStack *s) {
    s->top = -1;
}

//判断栈空
bool stackEmpty(SqStack s) {
    return s.top == -1;  //如果栈是空的,那么就会返回true
}

//新元素入栈
bool push(SqStack *s, int x) {
    if (s->top == MAX_SIZE - 1) //如果栈已满,返回false
        return false;
    s->data[++(s->top)] = x;  //否则先将栈顶指针的值加1,然后再使用增加后的栈顶指针指向的位置作为数组下标,将x存储到data数组中
    return true;
}

//出栈
bool pop(SqStack *s, int *x) {
    if (s->top == -1) { //因为栈已空,再出栈报错返回false
        return false;
    }
    *x = s->data[s->top--]; //从栈顶取出一个元素并赋值给x*,然后将栈顶指针减1,即把栈顶指针指向它下方的元素
    /*为什么给x*呢?因为需要通过指针参数才能把栈的元素值传递出去,进而传给topElem*/

    return true;
}

//括号匹配算法的主体
bool bracketCheck(char str[]) {
    SqStack s;    
    initStack(&s);
    for (int i = 0; i < strlen(str); i++) {
        if (str[i] == '<' || str[i] == '(' || str[i] == '{' || str[i] == '[') {
            push(&s, str[i]);
        } else {
            if (stackEmpty(s)) {
                return false;
            }
            int topElem;  //topElem作为中间变量,记录从栈中弹出的栈顶元素
            if (!pop(&s, &topElem)) { //如果取出栈顶元素失败,说明栈为空,则匹配失败,返回false
                return false;
            }
            if (str[i] == '>' && topElem != '<') {
                return false;
            }
            if (str[i] == ')' && topElem != '(') {
                return false;
            }
            if (str[i] == ']' && topElem != '[') {
                return false;
            }
            if (str[i] == '}' && topElem != '{') {
                return false;
            }
        }
    }
    return stackEmpty(s); //栈空,说明所有括号都能匹配成功,返回true;否则说明还有没配成功的括号,返回false
}

int main() {
    char str[MAX_SIZE];  //接收字符串
    scanf("%s", str);
    if (bracketCheck(str)) printf("yes");
    else printf("no");
    return 0;
}

3.2 Chain stack implementation

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node* next;
} Node;

typedef struct {
    Node* top;
    int count;
} LinkedStack;

// 初始化链栈
void InitStack(LinkedStack* S) {
    S->top = NULL;
    S->count = 0;
}

// 判断栈空
bool StackEmpty(LinkedStack* S) {
    return S->count == 0;
}

// 新元素入栈
bool Push(LinkedStack* S, int x) {
    Node* node = (Node*)malloc(sizeof(Node));
    if (node == NULL) {
        return false;  // 内存分配失败,入栈失败
    }
    node->data = x;
    node->next = S->top;
    S->top = node;
    S->count++;
    return true;
}

// 弹出栈顶元素
bool Pop(LinkedStack* S, int* x) {
    if (StackEmpty(S)) {
        return false;  // 栈空,弹出失败
    }
    Node* node = S->top;
    S->top = node->next;
    *x = node->data;
    free(node);
    S->count--;
    return true;
}

// 读取栈顶元素
bool GetTop(LinkedStack* S, int* x) {
    if (StackEmpty(S)) {
        return false;  // 栈空,读取失败
    }
    *x = S->top->data;
    return true;
}

// 括号匹配检查
bool bracketCheck(char str[]) {
    LinkedStack S;
    InitStack(&S);
    for (int i = 0; i < strlen(str); i++) {
        if (str[i] == '<' || str[i] == '(' || str[i] == '{' || str[i] == '[') {
            Push(&S, str[i]);
        } else {
            if (StackEmpty(&S)) {
                return false;  // 栈空,匹配失败
            }

            int topElem;
            if (!Pop(&S, &topElem)) {
                return false;  // 弹出失败,匹配失败
            }
            if (str[i] == '>' && topElem != '<') {
                return false;  // 匹配失败
            }
            if (str[i] == ')' && topElem != '(') {
                return false;  // 匹配失败
            }
            if (str[i] == ']' && topElem != '[') {
                return false;  // 匹配失败
            }
            if (str[i] == '}' && topElem != '{') {
                return false;  // 匹配失败
            }
        }
    }
    return StackEmpty(&S);
}

int main() {
    char str[100000];
    scanf("%s", str);
    if (bracketCheck(str)) {
        printf("yes\n");
    } else {
        printf("no\n");
    }
    return 0;
}

 

Guess you like

Origin blog.csdn.net/m0_56494923/article/details/129244767