栈的应用:括号匹配
1 括号匹配问题
1.1 介绍
看下列代码,思考括号合法性规律
void test(){
int a[10][10];
int x=10*(20*(1+1)-(3-2));
printf("加油!奥利给!");
}
最后出现的左括号最先被匹配(1LIFO)
[!NOTE] 🙍重点
- 遇到左括号就入栈
- 遇到有括号,就“消耗”一个左括号
1.2 真题演练
力扣原题:https://leetcode.cn/problems/valid-parentheses/
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
1.2.1 代码展示区
/**
* @author five-five * @created 2022/5/20 * */#include "stdbool.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#define MAXSIZE 10*10*10*10
typedef struct Stack {
char data[MAXSIZE];
int top;
} Stack;
bool initStack(Stack **stack) {
*stack = (Stack *) malloc(sizeof(Stack));
if (NULL == *stack) {
return false;
}
(*stack)->top = -1;
return true;
}
bool push(Stack *stack, char c) {
if (NULL == stack || stack->top == MAXSIZE - 1) {
return false;
}
stack->top++;
stack->data[stack->top] = c;
return true;
}
bool pop(Stack *stack, char *c) {
if (NULL == stack || stack->top < 0) {
return false;
}
*c = stack->data[stack->top];
stack->top--;
return true;
}
bool empty(Stack *stack) {
return stack == NULL || stack->top < 0;
}
bool isValid(char *s) {
Stack *stack;
initStack(&stack);
size_t len = strlen(s);
if (len % 2 != 0) {
return false;
}
for (int i = 0; i < len; ++i) {
char left = s[i];
//左括号入栈
if (left == '{' || left == '(' || left == '[') {
push(stack, left);
} else {
//有右括号,但是栈空,那必然是错误的
if (empty(stack)) {
return false;
}
char right;
pop(stack, &right);
//左右括号开始匹配
if (left == ')' && right != '(') {
return false;
}
if (left == '}' && right != '{') {
return false;
}
if (left == ']' && right != '[') {
return false;
}
}
}
//最后的判断,栈匹配完毕之后就是空
return empty(stack);
}
int main() {
//0表示false,1表示true
bool flag = isValid("((");
printf("%d", flag);
return 1;
}
[!info] 用栈实现括号匹配:
- 依次扫描所有字符
- 遇到左括号入栈
- 遇到右括号弹出栈顶元素
- 检查是否匹配
- 匹配失败的原因:
- 左括号单身
- 右括号单身
- 左右括号不匹配
- 最后记得判断栈是否为空
[!NOTE] 重点
一定一定要把基本的数据结构的那些操作在脑海中过一遍
可用“栈”实现该特性 ↩︎