最长括号匹配问题

最长括号匹配:

给定字符串,仅包含左括号‘(‘和右括号‘)‘,它可能不是括号匹配的,设计算法找出最长匹配的括号子串,返回该字串的长度。

如:

(() : 2

()() : 4

()(()) : 6

()(())) : 6

(((()())) : 8

1、首先采用栈的存储方式来解决这个问题:

假设起始匹配位置为start = -1,最大匹配长度为MaxLen,考虑第i位字符c:

如果c是左括号,则进行压栈;

如果c为右括号,它一定与栈顶左括号匹配:

(1)如果栈为空,表示没有匹配左括号,start = i,为下一次匹配做准备;

(2)如果栈不空,出栈。再判断栈是否为空,若为空,MaxLen = max(MaxLen,i-start);若不为空, MaxLen = max(MaxLen,i-栈顶元素位置);

程序实现:

 1 int GetLongestParentheses(const char* p){
 2     int size = (int)strlen(p);
 3     stack<int> s;
 4     int MaxLen = 0;
 5     int start = -1;//左括号的前一个位置
 6     for(int i=0;i<size;i++){
 7         if(p[i]==‘(‘){//左括号压栈
 8             s.push(i);
 9         }
10         else{//为右括号的情况
11             if(s.empty())
12                 start = i;
13             else{
14                 s.pop();
15                 if(s.empty())
16                     MaxLen = max(MaxLen,i-start);
17                 else
18                     MaxLen = max(MaxLen,i-s.top());
19             }
20         }
21     }
22     return MaxLen;
23 }

2、采用深度deep表达,将空间复杂度由O(n)降低为O(1).

程序实现:

 1 int GetLongestParentheses1(const char* p){
 2     int size = (int)strlen(p);
 3     int MaxLen = 0;
 4
 5     int deep = 0;//遇到了多少左括号
 6     int start = -1;//最深第一个左括号的前一个位置
 7     for(int i=0;i<size;i++){
 8         if(p[i]==‘(‘)
 9             deep++;
10         else{
11             deep--;
12             if(deep==0){
13                 MaxLen = max(MaxLen,i-start);
14             }else if(deep<0){
15                 deep = 0;
16                 start = i;
17             }
18         }
19     }
20
21     deep=0;//遇到了多少右括号
22     start = size;//最深右括号的后一个位置
23     for(int i=size-1;i>=0;i--){
24         if(p[i]==‘)‘)
25             deep++;
26         else{
27             deep--;
28             if(deep==0)
29                 MaxLen = max(MaxLen,start-i);
30             else if(deep<0){
31                 deep = 0;
32                 start = i;
33             }
34         }
35     }
36     return MaxLen;
37 }

两者比较且运行结果:

 1 #include <iostream>
 2 #include <stack>
 3 #include <cstring>
 4 using namespace std;
 5
 6 int GetLongestParentheses(const char* p){
 7     int size = (int)strlen(p);
 8     stack<int> s;
 9     int MaxLen = 0;
10     int start = -1;//左括号的前一个位置
11     for(int i=0;i<size;i++){
12         if(p[i]==‘(‘){//左括号压栈
13             s.push(i);
14         }
15         else{//为右括号的情况
16             if(s.empty())
17                 start = i;
18             else{
19                 s.pop();
20                 if(s.empty())
21                     MaxLen = max(MaxLen,i-start);
22                 else
23                     MaxLen = max(MaxLen,i-s.top());
24             }
25         }
26     }
27     return MaxLen;
28 }
29
30 int GetLongestParentheses1(const char* p){
31     int size = (int)strlen(p);
32     int MaxLen = 0;
33
34     int deep = 0;//遇到了多少左括号
35     int start = -1;//最深第一个左括号的前一个位置
36     for(int i=0;i<size;i++){
37         if(p[i]==‘(‘)
38             deep++;
39         else{
40             deep--;
41             if(deep==0){
42                 MaxLen = max(MaxLen,i-start);
43             }else if(deep<0){
44                 deep = 0;
45                 start = i;
46             }
47         }
48     }
49
50     deep=0;//遇到了多少右括号
51     start = size;//最深右括号的后一个位置
52     for(int i=size-1;i>=0;i--){
53         if(p[i]==‘)‘)
54             deep++;
55         else{
56             deep--;
57             if(deep==0)
58                 MaxLen = max(MaxLen,start-i);
59             else if(deep<0){
60                 deep = 0;
61                 start = i;
62             }
63         }
64     }
65     return MaxLen;
66 }
67 int main()
68 {
69     char str1[] = "(()";
70     char str2[] = "()()";
71     char str3[] = "()(())";
72     char str4[] = "()(()))";
73     char str5[] = "(((()()))";
74     cout<<GetLongestParentheses(str1)<<endl;
75     cout<<GetLongestParentheses(str2)<<endl;
76     cout<<GetLongestParentheses(str3)<<endl;
77     cout<<GetLongestParentheses(str4)<<endl;
78     cout<<GetLongestParentheses(str5)<<endl;
79     cout<<"----------------deep O(1)--------------------"<<endl;
80     cout<<GetLongestParentheses1(str1)<<endl;
81     cout<<GetLongestParentheses1(str2)<<endl;
82     cout<<GetLongestParentheses1(str3)<<endl;
83     cout<<GetLongestParentheses1(str4)<<endl;
84     cout<<GetLongestParentheses1(str5)<<endl;
85     return 0;
86 }

转载请注明出处:

C++博客园:godfrey_88

http://www.cnblogs.com/gaobaoru-articles/

时间: 2024-10-11 17:47:17

最长括号匹配问题的相关文章

顺序栈(进制转换 + 括号匹配 + 判断栈表 + 最长括号匹配长度)

#include <stdio.h> #include <stdlib.h> #include <iostream> using namespace std; #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define STACK_INIT_SIZE 100 #define STACKLINCREMENT 10

栈应用——最长括号匹配

问题描述: 给定字符串,仅包含左括号'('和右括号')',它可能不是括号匹配的,设计算法,找出最长的括号字串,并返回字串的长度. 如: ((): 2 ()(): 4 ()(()):6 (()()): 6 思路分析: 记起始位置start = -1,最大匹配长度为max 考虑当前位置i的符号: 如果是'(',直接入栈: 如果是')': 如果栈空,则起始位置更新为i; 如果栈不空,则肯定能与栈顶的左括号匹配,然后考虑弹出一个左括号后的栈: 若栈空,则说明此次是一个匹配,匹配长度为:i-start,然

括号匹配(字符串)

问题描述:检查字符串表达式中的括号是否匹配:左括号数目同有括号数目不相等即为不匹配:去除多余的左括号或者右括号,优先保留先出现的括号:匹配后去除无效的括号:如:((表达式)) 应为(表达式):只考虑小括号,不考虑先出现右括号的情况:要求实现函数: (字符串最长长度为60:表达式正确性不需要考虑)void Bracket(char* src, char* dst);如果匹配则通过dst 输出原串:如果不匹配则根据要求去处多于括号后通过dst 输出匹配后的串示例输入:12+(345*25-34) 输

eclipse config 5 括号匹配插件

这个插件将可以使你的eclipse 具备sourceinsight的另一项大招 当函数体过长时,嵌套层次过多时,在大括号结尾显示这个大括号对应的开始字符 方便查看层次问题,当然所有的编码规范不推荐嵌套层次过多. 如下图 虚线部分即是 同时该插件还可以支持多层级括号匹配时 不同的层级使用不同的亮度来进行显示,清晰明了 还支持鼠标划过时括号匹配动态更新,我一般关闭这个选项,个人癖好,喜欢光标在哪里显示哪里的括号匹配情况. 插件名称 Bracketeer for C/C++ (CDT) 插件安装地址

水了两道括号匹配

POJ 1141 给一段括号序列,要求增加最少的括号,使之合法,输出序列. dp[i][j]表示使给定序列的i到j成为合法序列所需添加的最少括号数,dp[0][length-1]即是答案,转移的话,如果s[i]和s[j]可以匹配那么dp[i][j] = dp[i+1][j-1],否则就考虑在中间选择一个位置m,使分割成的两个序列各自成为合法序列.方案的话就是多开一个数组记录然后递归输出.状态是从长度小的序列转移到长度长的序列,所以两层循环,外层枚举长度,内层枚举头位置即可.写成记忆化搜索简单一点

NYOJ15括号匹配

NYOJ15括号匹配 括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说

jzyzoj 栈——P1148:括号匹配加强版

括号匹配加强版 描述 Description 对于一个由(,),[,]括号组成的字符串,求出其中最长的括号匹配字串. 具体来说,满足如下条件的字符串成为括号匹配的字符串: (1) (),[] 是括号匹配的字符串. (2) 若A是括号匹配的串,则(A)或[A] 是括号匹配的字符串. (3) 若A和B都是括号匹配的字符串,则A+B也是括号匹配的字符串.(这里的+是字符串的加法运算). 例如:(),[],([]),()() 都是括号匹配的字符串,而][,[( ]),(]则不是. 字符串A的子串是指由A

【数据结构】栈的应用 括号匹配

括号配对问题: 假设一个表达式中包含三种类型的括号:(),{ },[],嵌套顺序任意 { [()()] } 1  2 3 4  5  6 7  8 引入"期待的急迫程度"概念,例如当接受第一个括号 { ,则它期待与第8个 } 匹配,然而当接受到第二个 [ 时,此时[最期待和第七个 ] 匹配. #ifndef _MATCH_H_ #define _MATCH_H_ #include<iostream> #include <malloc.h> #include &l

OJ1147括号匹配加强版(栈)

惨兮兮的被刷掉2%的通过率后在经过思考和dalao的指点后终于A掉了这道题 强烈建议修改这题的样例,实在太迷惑人,各种错误算法都能过 比如说这是一份错误代码,看懂了也不要学思路,和正解不知道差到哪里去了: 惨兮兮,WA掉代码: #include <iostream> #include <iomanip> #include <cmath> #include <cstdio> #include <cstring> #include <algor