leetcode-10 Regular Expression Matching

来源:互联网 发布:男士卡包 知乎 编辑:程序博客网 时间:2024/04/29 05:54

Implement regular expression matching with support for ‘.’ and ‘*’.

‘.’ Matches any single character.
‘*’ Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
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

看着题目就难懂,找规律都有些复杂。纠结了几天,还是想不出好的方法,只得去discuss学习学习,然后百度了一下,发现大神太多,水货怎么活………
下面是借鉴过来的,别人的分析与思路,必须好好学习!感谢大神的分享!!
http://blog.csdn.net/hopeztm/article/details/7992253
这是一道动态规划题。
题目意图很简单,就是实现一个正则表达式匹配的判定函数。 特别要说一下的是 .* 这个格式,因为不是经常用,最开始想错了,以为是先匹配”.” 然后 “.” 匹配成什么,后面的 * 就扩展什么。

其实核心的思路是一个动态规划

dp[i][j]表示字串 s[i…len(s)], p[j…len(p)] 是否可以匹配。

那么状态转移方程如下:

dp[i][j] =

c1. p[j+1] != *. if s[i] == p[j] dp[i][j] = dp[i+1][j+1]

else dp[i][j] = false

c2 p[j+1] == ‘’ (这个情况下,要扩展 , dp[i][j] 从拓展的情况下,选择一个是真的结果)

if( s[i] == p[j] || p[j] == ‘.’ && (*s) != 0) 当s[i] 和 p[j] 一样的时候,例如 aba, a*b这个时候,i = 0, j = 0, 自然可以匹配a a
如果p[j] == . 因为他可以匹配任何字符,所以和相等关系有基本一样的方式。
并且每一步匹配都要递增 i 的值,如果有成立的,则返回true,否则到匹配终了,返回通配符匹配完成后的结果。

别人写的C代码

bool isMatch(char* s, char* p) {    if (s == NULL || p == NULL) return false;    if (*p == '\0') return *s == '\0';    // ".*" matches "", so we can't check (*s == '\0') here.    if (*(p + 1) == '*')    {        // Here *p != '\0', so this condition equals with        // (*s != '\0' && (*p == '.' || *s == *p)).        while ((*s != '\0' && *p == '.') || *s == *p)        {            if (isMatch(s, p + 2)) return true;            ++s;        }        return isMatch(s, p + 2);    }    else if ((*s != '\0' && *p == '.') || *s == *p)    {        return isMatch(s + 1, p + 1);    }    return false;}

还有其他大神的代码,分别用的是递归和动态规划。
其中递归的代码与上面的方法一样。动态规划则不同。看起来,递归的代码简洁,思路清晰。动态规划的代码,比较繁琐。不过明显,动态规划的代码运行速度快,递归的由于嵌套所以较慢。算是各有所长。
https://leetcode.com/discuss/28725/c-recursive-solution-and-dp-solution

recursive solution:bool isMatch(const char *s, const char *p) {    if(!*p) return !*s;    if(!*s) return *(p+1)=='*' && isMatch(s, p+2);    if(*(p+1)=='*')        return isMatch(s, p+2) || (*s==*p || *p=='.') && isMatch(s+1, p);    else        return (*s==*p || *p=='.') && isMatch(s+1, p+1);}DP solution:bool isMatch(const char *s, const char *p) {    const int m=strlen(s), n=strlen(p);    bool arr[m+1][n+1];    fill_n(*arr, (m+1)*(n+1), false);    arr[0][0]=true;    for(int j=2; j<=n; j+=2)        if(arr[0][j-2] && p[j-1]=='*')            arr[0][j]=true;        else            break;    for(int i=1; i<=m; ++i)        for(int j=1; j<=n; ++j)            if(p[j-1]=='*')                arr[i][j]=arr[i][j-2] || arr[i-1][j] && (s[i-1]==p[j-2] || p[j-2]=='.');            else                arr[i][j]=arr[i-1][j-1] && (s[i-1]==p[j-1] || p[j-1]=='.');    return arr[m][n];}

路漫漫其修远兮啊……

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 微信号被骗走然后骗了朋友钱怎么办 微信手机充值不到帐怎么办 中银香港密码器坏了怎么办 香港恒生银行的编码器丢了怎么办 淘宝拍下订单发货物流不显示怎么办 wish查到仿品审核变慢怎么办 淘宝卖家订单号错误无法修改怎么办 顺丰快递运单号微信扫描取消怎么办 买的王者荣耀号有守护平台怎么办 融e联登录密码错三次怎么办 金融e家u盾密码忘了怎么办 用工行网银转账后想取消交易怎么办 工行融e借没有密码器怎么办 工行融e借密码器丢了怎么办 工行融e联手机登录密码忘记怎么办 领导给员工抱怨工作太烦怎么办 员工抱怨忙的忙死闲的闲死怎么办 爱上骗我进传销的人该怎么办 尚赫辟谷期间吃了东西怎么办 肾结石掉在输尿管里面好痛怎么办 寄的快递快递单号找不到了怎么办 手机停机但是快递是这个号码怎么办 百世通快递卡在一个地方没动怎么办 电信无限流量20g用完了怎么办 至尊宝qq密保手机被更换怎么办 至尊宝账户密保手机被改怎么办 照片放到私密相册找不到了怎么办 出口报关报错境内货源地怎么办? 微信提现未到账交易记录删了怎么办 支付宝忘记密码就可以登陆怎么办 电脑上登陆QQ忘记密码了怎么办? 电脑被管理员限制登录微信了怎么办 快手绑定的手机号丢了登不上怎么办 快手绑定的手机号丢了登不了怎么办 苹果id有手机号不知道密码怎么办 微信号不是手机号不知道密码怎么办 手机发短信说程序发生错误怎么办 派派游戏崇物等级低怎么办 轻微事故没有报警后面有问题怎么办 苹果6sp手机接电话声音小怎么办 用手机号办的移动宽带到期了怎么办