zoukankan      html  css  js  c++  java
  • 最长括号匹配问题

    最长括号匹配:

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

    如:

    (() : 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/

    转载请注明出处: C++博客园:godfrey_88 http://www.cnblogs.com/gaobaoru-articles/
  • 相关阅读:
    学习MyBatis时报的错
    Day01
    PAT乙级01
    基于python-django框架的支付宝支付案例
    单线程与多线程的应用 --Python3
    Python异常 --Python
    有四个数字能组成多少个互不相同的三位数 --Python
    with as用法 --Python
    采用霍夫曼编码(Huffman)画出字符串各字符编码的过程并求出各字符编码 --多媒体技术与应用
    函数和代码复用 --Python
  • 原文地址:https://www.cnblogs.com/gaobaoru-articles/p/5448792.html
Copyright © 2011-2022 走看看