Winter-2-STL-B Brackets 解题报告及测试数据

Time Limit:2000MS     Memory Limit:65536KB

Description

Given a string consisting of brackets of two types find its longest substring that is a regular brackets sequence.

Input

There are mutiple cases in the input file.

Each case contains a string containing only characters ‘(’ , ‘)’ , ‘[’ and ‘]’ . The length of the string does not exceed 100,000.

There is an empty line after each case.

Output

Output the longest substring of the given string that is a regular brackets sequence.

There should be am empty line after each case.

Sample Input

([(][()]]()

 

([)]

 

Sample Output

[()]

 

 

题解:

这道题是用栈进行括号的匹配过程。具体思路如下:

1、使用字符串str[100005]储存输入的括号,遍历操作。每个字符有三种情况,(1)“(]”或“[)”属于无法匹配,之前栈中的括号无法进行后续匹配,所以进行清空栈。(2)当前遍历到的字符可以与栈顶元素抵消,那么此时用到了一个标记数组p,将栈顶元素和当前元素位置标记为1。(3)不属于前两种情况,进栈等待匹配。由函数 can_place(char)进行判断。

2、将匹配位置都置1后,需要判断全为1最长子串,这很容易,使用st更新起始位置,maxl更新长度即可。     

 以下是代码:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
#include <cstring>
#include <utility>
using  namespace std;
char  str[100005];
int  p[100005];//标记括号成功匹配
stack<pair< char , int > >v;
int  can_place(char ch){//如果非法,返回0,可进栈,返回1,可与栈顶抵消,返回2
     if (v.empty()){
         if (ch ==  '('  || ch == '[')return 1;
         return  0;
     } else  switch(v.top().first){
         case '(' : if (ch == ']' ) return  0;if(ch==')')return 2;return 1;
         case '[' : if (ch== ')' ) return  0;if(ch==']')return 2;return 1;
     }
}
int  main(){
     //freopen("1.in","r",stdin);
     int  len;
     while ( scanf ( "%s" ,str)!=EOF){
         len =  strlen (str);
         memset (p,0, sizeof (p));
         for ( int  i=0;i<len;i++)
         switch (can_place(str[i])){
             case  0:while(!v.empty())v.pop();break;//遇到非法括号,清空栈
             case  1:v.push(make_pair(str[i],i));break;//若可以进栈,进栈
             case  2:p[i]=p[v.top().second]=1;v.pop();//若匹配出栈,将对应位置置1
         }
         while (!v.empty())v.pop();
         int  maxl=0,tl=0,t=0,st=0;
         for ( int  i=0;i<len;i++){//计算最长的全1子串
             if (!p[i]){
                 t=i+1;
                 tl=0;
             } else  tl++;
             if (maxl<tl){ //更新长度maxl及开始位置st
                 st=t;
                 maxl=tl;
             }     
         }
         for ( int  i=st;i< st+maxl;i++)
             printf ( "%c" ,str[i]);
         printf ( "\n\n" );
     }
}

以下是测试数据:

smaple input 

 

[](()](()[()])

 

()()[[](]

 

[][()()][(])

 

​sample output 

 

(()[()])

 

()()

 

[][()()]

 

 

你可能感兴趣的:(rack)