leetcode 10.正则表达式

Posted my-growth

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 10.正则表达式相关的知识,希望对你有一定的参考价值。

题目描述特别简洁:

技术图片

 

 

 先贴代码:

class Solution {
    public :
        bool isMatch(string s ,string p){
            int dp[100][100] = {0};                        
            s.insert(0,1,@);p.insert(0,1,@);           //为了将空字符考虑在内,初始化插入@方便之后的操作
            int ls = s.size(),lp = p.size();
            dp[0][0] = 1;                                  //初始化dp(p与s为空字符)
            for(int j = 1 ; j < lp; j++){
                for(int i = 0; i < ls; i ++){
                    if(i != 0 && (s[i] == p[j] || p[j] == .) && dp[i-1][j-1] == 1 ){     //直接匹配
                        dp[i][j] = 1;
                    }
                    else if(p[j] == *)                                                   //当p[j]为*时情况较为复杂
                    {
                        if(j - 2 >= 0 && dp[i][j - 2] == 1)                                //可以直接把零个随意字符通配Σ*忽略
                        {
                            dp[i][j] = 1;
                        }
                        else if(i !=  0 && (dp[i - 1][j]  == 1 || dp[i - 1][j - 1] == 1) && (s[i] == p[j - 1] || p[j-1] == .))       //将Σ*于n个Σ匹配
                        {
                            dp[i][j] = 1;
                        }
                    }
                }
            }
    //        for(int i = 0;i < lp; i++)                        //把dp打印出来用于debug
    //        {
    //            for(int j = 0;j < ls; j++)
    //            {
    //                cout << dp[j][i];
    //            }
    //            cout<<endl;
    //        }
            if(dp[ls - 1][lp - 1])
            {
                cout << "ture";
                return 1;
            }
            else{
                cout << "false";
                return 0;
            }
        }
}; 

 

通过如下的样例说明状态转移的过程(本题难就难在状态转移的方式比较多样,这也导致用简单的递归方法解题非常困难):

Case #1:

aaa

a*a

(如果将三个a直接用a*通配掉了那就直接得到了一个false)

Solution #1:

ture

DP(dpij) #1: 

(当s.substr(0,i)与p.substr(0,j)能够相互匹配时dpij = 1)

1 0 0 0      (空字符串)
0 1 0 0      (dpi-1  j-1 == 1 时 s[i] 与 p[j] 是等价的 就有 dpij = 1)
1 1 1 1      (p[j] == ‘*‘ 且 dpi  j-2 == 1 这表明 考虑dpij的时候 ‘*’ 与它之前的 ‘Σ’ 可以视作 0 个Σ 于是 两个子字符串匹配 dpij = 1) (p[j] == ‘*‘ 且 dpi-1  j == 1 且 s[i] 与 p[j-1]  (也就是Σ)能够匹配 则 dpij = 1)
0 1 1 1      (继续进行上面的状态转移,得到答案) 

Case #2:

abp

.*t

Solution #2:

false

(虽然.*匹配任意字符串但是加上个t就不行了)

DP(dpij) #2:

1 0 0 0
0 1 0 0
1 1 1 1
0 0 0 0

 

Case #3:

bbbopctf

b*.*ctf

(若只想到用.*匹配后面所有的字符便无法匹配“ctf”)

Solution #3:

ture

DP(dpij) #3:

1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0
0 1 1 1 1 0 0 0 0
1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1

技术图片

 

 

动态规划编写简单,优势明显。

 

以上是关于leetcode 10.正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode(算法)- 10. 正则表达式匹配

LeetCode 10 正则表达式匹配

Leetcode 10. 正则表达式匹配

Leetcode 10 regular expression matching (正则表达式匹配) (动态规划)

LeetCode(10. 正则表达式匹配)

LeetCode 10. 正则表达式匹配