- 👋 Hi, I’m @Beast Cheng
- 👀 I’m interested in photography, hiking, landscape…
- 🌱 I’m currently learning python, javascript, kotlin…
- 📫 How to reach me --> 458290771@qq.com
喜欢《数据结构》部分笔记的小伙伴可以订阅专栏,今后还会不断更新。🧑💻
此外,《程序员必备技能》专栏和《程序员必备工具》专栏(该专栏暂未开设)日后会逐步更新,感兴趣的小伙伴可以点一下订阅、收藏、关注!🚀
谢谢大家!🙏
括号示例
void test(){int a[10][10];int x = 10*(20*(1+1)-(3-2));printf("加油!奥里给!");
}
流程应该为:
- 遇到左括号就入栈
- 遇到右括号,就“消耗”一个左括号
- 处理完所有括号后,栈非空——左括号单身
- 因此写代码的时候,扫描完所有的括号后,还要检查是否栈空
- 如果栈非空,则匹配失败
算法实现
#define MaxSize 10
typedef struct{char data[MaxSize];int top;
}SqStack;/*
* 考试中可以直接使用栈的这些基本操作
* 但是建议要写上简短的说明接口分别是什么
*///初始化栈
void InitStack(SqStack &S)
//判断栈是否为空
bool StackEmpty(SqStack S)
//新元素入栈
bool Push(SqStack &S, char x)
//栈顶元素出栈,用x返回
bool Pop(SqStack &S, char &x)bool bracketCheck(char str[], int length){SqStack S; //声明一个栈InitStack(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); //检索完所有括号后,栈空说明匹配成功
}
需要注意的是,当前定义的最大长度是10
,如果长度不够了怎么办?
答:可以用链栈的方式来实现,不过在考试中用顺序栈来实现更方便,所以用顺序栈就可以了
练习:去掉代码中的基本操作,把相对应的逻辑换成对数组和top指针直接的判断和操作,动手实现完整代码!
答案:
- 先将基本操作替换一下
//首先,初始化栈
//将栈的top指针初始化为 -1,表示栈为空
S.top = -1;//判断栈是否为空
//也就是判断top是否为 -1,如果是,表示栈空
if(S.top == -1)//新元素入栈,将元素放在top指针所指位置的下一位,并将top指针 +1
if(S.top < MaxSize - 1){S.data[++S.top] = str[i];
}else{return false;
}//栈顶元素出栈,获取top指针所指位置的元素,并将top指针 -1
if(S.top != -1){topElem = S.data[S.top--];
}else{return false;
}
- 最终完整代码
#include <stdbool.h>
#include <stdio.h>#define MaxSize 10typedef struct{char data[MaxSize];int top;
}SqStack;bool bracketCheck(char str[], int length){SqStack S; //声明一个栈S.top = -1; //初始化栈for(int i = 0; i < length; i++){if(str[i] == '(' || str[i] == '[' || str[i] == '{'){if(S.top < MaxSize - 1){S.data[++S.top] = str[i]; //扫描到左括号,入栈}else{return false; //栈满,匹配失败}}else if(str[i] == ')' || str[i] == ']' || str[i] == '}'){if(S.top == -1) //扫描到右括号,且当前栈空return false; //匹配失败char topElem;if(S.top != -1){topElem = S.data[S.top--]; //栈顶元素出栈}else{return false; //栈空,匹配失败}if((str[i] == ')' && topElem != '(') ||(str[i] == ']' && topElem != '[') ||(str[i] == '}' && topElem != '{'))return false; //匹配失败}}return S.top == -1; //检索完所有括号后,栈空说明匹配成功
}int main(){char str[] = "{[()]}";int length = sizeof(str) / sizeof(str[0]) - 1;bool result = bracketCheck(str, length);if(result)printf("括号都是成对的\n");elseprintf("括号不是成对的\n");return 0;
}
以上代码的问题解答:
- 为什么用
S.top == MaxSize - 1
这个条件来判断是否栈满?为什么MaxSize要-1 ?- 在使用数组实现栈的情况下,我们需要知道数组的最大容量。假设数组的最大长度为
MaxSize
,那么数组的索引范围是从0
到MaxSize - 1
。也就是说,数组中最后一个位置的索引是MaxSize - 1
。 S.top
:栈顶指针,指向当前栈顶元素的位置;MaxSize - 1
:数组的最大索引。- 如果
S.top
正好等于MaxSize - 1
,说明栈顶已经在数组的最后一个位置,因此栈中已经没有空余的空间可以容纳更多的元素,栈已经满了。
- 在使用数组实现栈的情况下,我们需要知道数组的最大容量。假设数组的最大长度为
S.data[++S.top] = str[i]; // 入栈
时,是先将指针+1,还是先压入数据?- 在这条语句中,
++S.top
是一个前置自增操作。这意味着:S.top
会先增加 1,然后新值会被用作索引来存放新元素str[i]
- 也就是说,
S.top
会先增加一,然后指向下一个位置,然后在指向的这个位置里面插入元素str[i]
- 在这条语句中,
str[i]
是什么意思?其中的i
又是什么意思?str
:是一个字符数组(字符串),它包含了需要被检查的括号字符。i
:是一个整数,作为循环变量,表示当前在数组str
中的索引。循环遍历str
数组中的每一个字符,通过str[i]
来访问str
数组在第i
个位置的字符
- 在这个
for
循环中,只要有任意一次匹配失败,就会中断循环,并且返回false