Leetcode : Regular Expression Matching

原创 2015年07月08日 15:45:31

对于leetcode上这个题目,我用了不少时间来消化。
题目大意如下:


实现两个字符串s,t的匹配,其中t字符串中的
‘.’ 能匹配任何一个字符.
‘*’ 能充当0个或者多个前面一个字符.
匹配结果要覆盖整个字符串

几个例子:
isMatch(“aa”,”a”) → false
isMatch(“aa”,”aa”) → true
isMatch(“aaa”,”aa”) → false
isMatch(“aa”, “a*”) → true
isMatch(“aa”, “.*”) → true
isMatch(“ab”, “.*”) → true
isMatch(“aab”, “c*a*b”) → true

比如说最后这个例子c*a*b 能够和aab匹配 就说明第一个* 充当了0个c,第二个 *充当了两个a。


该题有两种较为普遍的解法:递归和动规。以下我就两种方法进行简要的分析。

递归法

该题的一个难点就是当t字符串中出现了符号“ * ”时该如何处理,有时候一下子并不能够清晰的把代码给写出来。我们可以直观地想,出现“ * ”时,该“ * ”可以充当0个,1个,2个…前面的字符,充当的过程还需要满足条件 (s[i]==p[0]) 或者(p[i]==’.’ && s[i]!=’\0’)。 我们将每种可能都与s串进行一遍比较,若有一种可以匹配成功,即是匹配成功。

若t字符串中的当前匹配符号不是符号“ * ”就好办多了,我们直接对 s[i]==p[0] 或者 p[0]==’.’ 进行判断,若匹配成功,那么就可以进行下一步匹配。

参考代码如下:(参考别人)

//递归方法
bool isMatch(string s, string p) 
{
        if ( p.empty() ) return s.empty();
        // p[1]不是*
        if ( p[1]!='*' )
        {
            return ( s[0]==p[0] || (p[0]=='.' && !s.empty()) ) && isMatch(s.substr(1), p.substr(1));
        }
        // p[1]是*
        int i = 0;
        for ( ; s[i]==p[0] || (p[0]=='.' && i<s.size()); ++i)
        {// * 可以充当0个,1个,2个...p[0] 但必须满足匹配条件
            if ( isMatch(s.substr(i), p.substr(2)) ) return true; 
        }
        // p[1] 是 * 但是 p[0] != s[i]
        return isMatch(s.substr(i), p.substr(2));
}

动态规划法

若是对动态规划较为熟悉的人可能对于该方法可能更顺手些。

我们提供一个二维空间集合f[i][j] 其表示字符串s[0..i-1]能否和t[0…j-1]匹配成功,我们很快可以得到动态规划转移方程

  • 当t[j-1]!=’*’时 f[i][j] = f[i-1][j-1] && ( s[i-1] == t[j-1] )

这个很好理解,s[i-1]和t[j-1]若相同,那么其s[0…i-2] 至 t[0…j-2]仍然能匹配成功时,那么这两段字符串就是匹配成功。

  • 当t[j-1]==’*’时 t[j-1]可以充当0个或者多个t[j-2],只要满足以下两个条件中任何一个,f[i][j] 结果即为true
    • t[j-1]充当0个t[j-2] : f[i][j] = f[i][j-2]
    • t[j-1]充当1个及以上t[j-2] :f[i][j] = (s[i - 1] == p[j - 2] || ‘.’ == p[j - 2]) && f[i - 1][j]

上述动规方程中的 f[i - 1][j] 包含了 t[j-1]充当2个,3个…多个t[j-2] 的所有可能性,并且动规过程中,我们已经计算并保存了结果。

参考代码如下:(参考别人)

bool isMatch(string s, string p) {

 int m = s.size(), n = p.size();
        vector<vector<bool>> f(m + 1, vector<bool>(n + 1, false));

        f[0][0] = true;//空串与空串匹配成功
        for (int i = 1; i <= m; i++)//s串与空串匹配结果为false
            f[i][0] = false;
        // p[0..j - 1] 能与空串匹配 需满足 p[j - 1]=='*' 并且 p[0..j - 3] 能与空串匹配
        for (int j = 1; j <= n; j++)
            f[0][j] = j > 1 && '*' == p[j - 1] && f[0][j - 2];

        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                if (p[j - 1] != '*')
                    f[i][j] = f[i - 1][j - 1] && (s[i - 1] == p[j - 1] || '.' == p[j - 1]);
                else
                    f[i][j] = f[i][j - 2] || (s[i - 1] == p[j - 2] || '.' == p[j - 2]) && f[i - 1][j];

        return f[m][n];
}

两种方法不同的思想,其中有相通的部分,都能解决问题,记录一下以便以后回顾。

版权声明:本文为博主原创文章,未经博主允许不得转载。

【LeetCode010算法/编程练习C++】Regular Expression Matching//挺烦的一条……

10. Regular Expression Matching Total Accepted: 113015 Total Submissions: 481908 Difficulty: ...
  • zmdsjtu
  • zmdsjtu
  • 2016年12月27日 16:09
  • 505

正则表达式(Regular Expression)基本语法

一、简介 为什么需要正则表达式? 文本的复杂处理正则表达式的优势和用途? 一种强大而灵活的文本处理工具; 大部分编程语言、数据库、文本编辑器、开发环境都支持正则表达式。正则表达式定义: 正如...
  • scgaliguodong123_
  • scgaliguodong123_
  • 2015年04月29日 22:00
  • 3938

浅谈正则表达式(Regular Expression)

一、什么是正则表达式? 简单的说:正则表达式(Regular Expression)是一种处理字符串匹配的语言; 正则表达式描述了一种字符串匹配的模式,可以用来检查一个字符串是否含有某种子串,对匹...
  • u014421422
  • u014421422
  • 2015年01月07日 09:17
  • 460

简单的正则表达式匹配 Regular Expression Matching

题目源自于Leetcode。 只需要支持两个匹配符*和.。 '.' Matches any single character. '*' Matches zero or more of the prec...
  • luckyjoy521
  • luckyjoy521
  • 2013年10月13日 22:41
  • 2070

工具分享--RegularExpressionTool(正则表达式测试工具)

最近翻电脑硬盘,意外发现了一个自己开发的正则测试工具。至从开发完该工具后,就一直很少使用它,比较可惜,现在把它开源出来分享给大家。下面是该工具的一些截图,发来给各位围观下:主界面 测试正则,能察看组捕...
  • ghostbear
  • ghostbear
  • 2013年03月11日 09:41
  • 2532

算法设计与分析(7)-- Regular Expression Matching(难度:hard)

Regular Expression Matching
  • alexlau8
  • alexlau8
  • 2017年04月13日 22:14
  • 133

正则表达式的灾难性回溯

最近项目上在做Fortify安全漏洞扫描。其中有一项漏洞扫描规则为:Denial of Service: Regular Expression。是由于正则表达式带来的DOS攻击。       由于F...
  • baidu_27487573
  • baidu_27487573
  • 2017年06月11日 20:56
  • 368

Regular Expression 正则表达式 笔记

匹配: {大括号和括号内的任意内容} 用例:编辑ass字幕时,批量去除样式 应用【Aegisub】:{(? 应用【EditPlus】:{.*} 文本内容: {\blur3\fnFZHei-B01S...
  • jx520
  • jx520
  • 2015年10月05日 11:32
  • 475

正则表达式——Regular Expression

正则表达式中分为三种东西:字符   数字   空格 正则表达式:(java.util.regex中)处理字符串,字符的匹配perl语言是运用正则表达式很好的语言留下e-mile从网页中揪出来e-...
  • qq_31820885
  • qq_31820885
  • 2016年05月02日 19:23
  • 176

正则表达式 regular expression(五)

注:本文内容为摘自Mastering regular expressions(《精通正则表达式》)的笔记。 1.perl中对于嵌套括号的变量$1,$2等的保存: 2.字符串的元字符中有一些...
  • jiahchen
  • jiahchen
  • 2017年05月06日 15:03
  • 104
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Leetcode : Regular Expression Matching
举报原因:
原因补充:

(最多只允许输入30个字)