CodeVS2058 括号序列 题解

来源:互联网 发布:手机淘宝实人认证在哪 编辑:程序博客网 时间:2024/06/03 19:24

这是本人人生中第一次写博客,心情有一丝小激动呢!新手上路,望各老司机多多包容!

那么言归正题:

个人观点:对于任何一个题目,解题时,我们脑海中应当首先出现解决本问题的一个基本框架,再对基本框架进行细节填充。在真正编写程序时,“基本框架”往往体现在主函数(main)中,而“细节填充”则体现在主函数中调用的各个子函数。对于本题,我们要做的事情是去判断一个含有“(){}[]<>”这几种括号的序列是否是满足条件的“规则序列”,那么基本框架也能够非常容易地想象出来:

1.读入——要读入测试数据组数N和N个待判断的序列;

  2.判断——这里需要调用一个“Judge”函数;

  3.输出——如果是输出“TRUE”,反之输出“FALSE”。

当你想到这里,我估计主函数也应该在你手下不由自主地敲出来了吧。

#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;int N, L;char s[2000000+2];char stack[2000000+2]={'0'};int p = 0;int main() {scanf("%d", &N);for(int i = 0; i<N; ++i){scanf("%s", s);L = strlen(s);Judge(s, L) ? printf("TRUE\n") : printf("FALSE\n");p = 0;}return 0;}


基本框架解决了,下面要做的就是对这个基本框架进行“填充”了,也就是“Judge”函数到底该怎么写。

首先它一定是bool类型。(恩……废话……)

既然“规则序列”中的括号都是成对的,那么长度L必定是偶数,如果是奇数我们也不必花时间判断了。

那么……

bool Judge(char Get[], int len){if(!len%2) return false;}
现在重点来了!

我们该如何利用“栈”来解决这个问题呢?大致思路为:从左到右对待判断序列s进行扫描,如果遇到左括号,入栈;如果遇到右括号,与栈顶元素比较。如果配对,栈顶元素出栈,否则失配,输出“FALSE";判断完成后,如果栈空正确,否则”FALSE“;

那么如何进行比较?如何判断他到底是左括号还是右括号?

在这里我利用了一个char类型的常量数组code,角标0~3的元素均为左括号,4~7均为右括号。并且对于角标为i(i<=3)的左括号来说,角标为i+4的右括号便是他的对应右括号。那么在扫描序列s的时候,我们可以利用一个Find_code函数查询s[ i ]在code数组里的对应角标n,如果n<=3说明它是左括号,就入栈;否则说明它是右括号,弹出栈顶stack[ p ],查询stack[ p ]的对应角标m,如果n-4==m,说明s[ i ]和stack[ p ]为一对对应括号,配对成功。反之,“FALSE”!

const char code[]={'(', '[', '{', '<', ')', ']', '}', '>'};int Find_code(char Get){for(int i = 0; i<8; ++i) if(code[i] == Get) return i;}bool Judge(char Get[], int len){if(!len%2 || Find_code(*Get)>3) return false;stack[++p] = *Get;for(int i = 1; i<len; ++i){if(Find_code(Get[i])<=3) stack[++p] = Get[i];else{if(!p) return false;if(Find_code(Get[i])-4 != Find_code(stack[p--])) return false;}}return (p ? false : true);}

下面是总代码:

#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;const char code[]={'(', '[', '{', '<', ')', ']', '}', '>'};int N, L;char s[2000000+2];char stack[2000000+2]={'0'};int p = 0;int Find_code(char Get){for(int i = 0; i<8; ++i) if(code[i] == Get) return i;}bool Judge(char Get[], int len){if(!len%2 || Find_code(*Get)>3) return false;stack[++p] = *Get;for(int i = 1; i<len; ++i){if(Find_code(Get[i])<=3) stack[++p] = Get[i];else{if(!p) return false;if(Find_code(Get[i])-4 != Find_code(stack[p--])) return false;}}return (p ? false : true);}int main() {scanf("%d", &N);for(int i = 0; i<N; ++i){scanf("%s", s);L = strlen(s);Judge(s, L) ? printf("TRUE\n") : printf("FALSE\n");p = 0;}return 0;}

如果有错误欢迎指出噢!








原创粉丝点击