您的位置:首页 > 其它

最长括号匹配问题

2016-04-30 15:10 323 查看
最长括号匹配:

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

如:

(() : 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-栈顶元素位置);

程序实现:

int GetLongestParentheses(const char* p){
int size = (int)strlen(p);
stack<int> s;
int MaxLen = 0;
int start = -1;//左括号的前一个位置
for(int i=0;i<size;i++){
if(p[i]=='('){//左括号压栈
s.push(i);
}
else{//为右括号的情况
if(s.empty())
start = i;
else{
s.pop();
if(s.empty())
MaxLen = max(MaxLen,i-start);
else
MaxLen = max(MaxLen,i-s.top());
}
}
}
return MaxLen;
}


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

程序实现:

int GetLongestParentheses1(const char* p){
int size = (int)strlen(p);
int MaxLen = 0;

int deep = 0;//遇到了多少左括号
int start = -1;//最深第一个左括号的前一个位置
for(int i=0;i<size;i++){
if(p[i]=='(')
deep++;
else{
deep--;
if(deep==0){
MaxLen = max(MaxLen,i-start);
}else if(deep<0){
deep = 0;
start = i;
}
}
}

deep=0;//遇到了多少右括号
start = size;//最深右括号的后一个位置
for(int i=size-1;i>=0;i--){
if(p[i]==')')
deep++;
else{
deep--;
if(deep==0)
MaxLen = max(MaxLen,start-i);
else if(deep<0){
deep = 0;
start = i;
}
}
}
return MaxLen;
}


两者比较且运行结果:

#include <iostream>
#include <stack>
#include <cstring>
using namespace std;

int GetLongestParentheses(const char* p){
int size = (int)strlen(p);
stack<int> s;
int MaxLen = 0;
int start = -1;//左括号的前一个位置
for(int i=0;i<size;i++){
if(p[i]=='('){//左括号压栈
s.push(i);
}
else{//为右括号的情况
if(s.empty())
start = i;
else{
s.pop();
if(s.empty())
MaxLen = max(MaxLen,i-start);
else
MaxLen = max(MaxLen,i-s.top());
}
}
}
return MaxLen;
}

int GetLongestParentheses1(const char* p){
int size = (int)strlen(p);
int MaxLen = 0;

int deep = 0;//遇到了多少左括号
int start = -1;//最深第一个左括号的前一个位置
for(int i=0;i<size;i++){
if(p[i]=='(')
deep++;
else{
deep--;
if(deep==0){
MaxLen = max(MaxLen,i-start);
}else if(deep<0){
deep = 0;
start = i;
}
}
}

deep=0;//遇到了多少右括号
start = size;//最深右括号的后一个位置
for(int i=size-1;i>=0;i--){
if(p[i]==')')
deep++;
else{
deep--;
if(deep==0)
MaxLen = max(MaxLen,start-i);
else if(deep<0){
deep = 0;
start = i;
}
}
}
return MaxLen;
}
int main()
{
char str1[] = "(()";
char str2[] = "()()";
char str3[] = "()(())";
char str4[] = "()(()))";
char str5[] = "(((()()))";
cout<<GetLongestParentheses(str1)<<endl;
cout<<GetLongestParentheses(str2)<<endl;
cout<<GetLongestParentheses(str3)<<endl;
cout<<GetLongestParentheses(str4)<<endl;
cout<<GetLongestParentheses(str5)<<endl;
cout<<"----------------deep O(1)--------------------"<<endl;
cout<<GetLongestParentheses1(str1)<<endl;
cout<<GetLongestParentheses1(str2)<<endl;
cout<<GetLongestParentheses1(str3)<<endl;
cout<<GetLongestParentheses1(str4)<<endl;
cout<<GetLongestParentheses1(str5)<<endl;
return 0;
}




转载请注明出处:

C++博客园:godfrey_88

http://www.cnblogs.com/gaobaoru-articles/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: