括号匹配——精选推荐
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
括号匹配
括号匹配这个问题,说难好难,但是说简单好像也挺简单,主要就是看我们的思路是否清晰,条例是否清楚。
基本问题是:给定⼀串字符,可能包括括号、数字、字母、标点符号、空格,检查这⼀串字符中的( ) ,[ ],{ }是否匹配,匹配输出yes,反之输出no。
我们可以先确定最基本的逻辑,就是对输⼊的数⼀⼀判断,如果是左括号就存起来,等到有有括号的时候进⾏配对,配对成功继续输⼊,错了就可以退出了。
于是,数据结构⾃然⽽然就是⽤栈了,⽽我⽤的是顺序栈。
先说说我最开始的想法啦。
1. 由于⾸先要读⼊⼀串字符,⽽且包括空格,但是判断的时候只能⼀个⼀个判断,所以就先给个数组存这串字符,⽤下标表⽰单个字符。
2. 然后为了⽅便地控制循环,我⽤strlen取得了字符的长度。
3. 设置了⼀个result参数,⽤于表⽰括号是否匹配的状态,1表⽰匹配成功,0表⽰不匹配。
并将其初始化为1,这样可以避免额外讨论字符串中没有括号的情况。
(没有括号也算匹配成功)
4. 接下来就是匹配环节了。
遍历我们之前的数组,遇到左括号⼊栈;遇到右括号,把这个右括号和出栈的值尝试匹配,成功就继续扫描,失败不⽤扫描了,直接输出no吧。
但是由于我⽤result表⽰是否匹配,所以我选择吧result的值变为0,然后退出循环。
5. 遍历的循环结束后,判断是否匹配,即判断result为0还是为1。
看起来没啥问题,但接着考虑⼀下,由于我的result初值为1,即默认匹配,会不会存在⼀种情况使括号即使不匹配,但是由于没有改变result的值⽽导致错误呢?
那么来看看什么时候result会改变。
仅当扫描到右括号才会进⾏匹配尝试,⽽仅当匹配失败才会使result为0。
也就是说,不扫描到右括
号,result是没机会匹配的。
于是我们会想,只有左括号呢?如果没有对应的右括号,即使不匹配,result仍然为1。
那么就必须额外加⼀个条件来排除上述情况。
显然这种情况下,栈中⼀定有左括号,即栈⼀定⾮空。
那么反过来说,如果括号匹配,栈就⼀定为空。
于是想到最后判断匹配的条件是:result=1且栈为空。
关键代码如下:
1 cin.getline(a, 100);
2 length = strlen(a);
3for (int i = 0; i <= length; i++) { //
4if (a[i] == '(' || a[i] == '[' || a[i] == '{') { //左括号⼊栈
5 Push(stack, a[i]);
6 }
7else if (a[i] == ')' || a[i] == ']' || a[i] == '}') { //右括号,将其与出栈的字符尝试匹配
8 temp = Pop(stack);
9if (!((a[i] == ')'&&temp =='(' )|| (a[i] == ']'&&temp == '[') || (a[i] == '}'&&temp == '{'))) {
10 result = 0; //如果不匹配就将result赋0
11break;
12 }
13 }
14 }
15if (result == 1&&stack.base==stack.top) { //匹配⼀定栈空,排除⽆右括号匹配,只有左括号
16 cout << "yes";
17 }
18else {
19 cout << "no";
20 }
需要注意的是,栈顶指针所指的⼀直是顶元素的上⼀个。
因此⼊栈的时候,现赋值再让栈顶指针+1;⽽出栈要反过来,先-1再赋值。
⼀开始我先输出头指针的内容再让头指针减⼀,这就导致运⾏时错误。
因为我忘了头指针为栈顶+1,因此其所指没有确切的值,导致⾮法访问。