Aplicação de correspondência de pilha em colchetes (implementação C pura de pilha/pilha de cadeia)

Índice

1 Histórico do Problema

2 ideias específicas

3 implementação de código

3.1 Implementação de pilha sequencial

3.2 Implementação da pilha em cadeia


1 Histórico do Problema

  O problema de correspondência de parênteses da pilha refere-se a julgar se os parênteses podem ser combinados corretamente após uma determinada string (contém vários tipos de parênteses), ou seja, se cada parêntese esquerdo tem um parêntese direito correspondente para combiná-lo, e os parênteses esquerdo e direito parênteses devem começar com a ordem correta para corresponder.

Por exemplo, os parênteses na string "((()))" são correspondidos corretamente, mas os parênteses na string "()())" não.

 

2 ideias específicas

Este é o fluxograma fornecido por Wang Dao:

Figura 1 Fluxograma fornecido por Wang Dao

 

Parece um pouco difícil, deixe-me resumir, é muito simples, apenas alguns passos:

  1. Percorra a string fornecida e julgue cada caractere.
  2. Se o caractere for um parêntese de abertura, coloque-o na pilha.
  3. Se o caractere for um parêntese de fechamento, compare-o com o elemento superior da pilha para ver se esse elemento é um parêntese de abertura correspondente. Se for, remova o elemento superior da pilha e continue percorrendo; caso contrário, significa que os colchetes não correspondem e retornam false.
  4. Se a string for percorrida e a pilha estiver vazia, significa que todos os colchetes coincidem e retornam true; caso contrário, retorna false.

Observe que se a pilha estiver vazia quando o elemento estiver pronto para ser removido, isso significa que não há nenhum colchete de abertura correspondente ao colchete de fechamento e false é retornado.

3 implementação de código

Considere a última pergunta de amostra da Acwing como exemplo: 3693. Correspondência de colchetes - Banco de perguntas da AcWing

Formato de entrada

Um total de uma linha, contendo uma string que consiste em `<`,`(`,`{`,`[`,`>`,`)`,`}`,`]`.

Formato de saída

Saída `yes` se os parênteses na string de entrada corresponderem corretamente, caso contrário, saída `no`.

intervalo de dados

O comprimento da string de entrada não excede 10.000.

Exemplo de entrada:

    (){}

Exemplo de saída:

    sim

 

3.1 Implementação de pilha sequencial

#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 Implementação da pilha em cadeia

#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;
}

 

Acho que você gosta

Origin blog.csdn.net/m0_56494923/article/details/129244767
Recomendado
Clasificación