码迷,mamicode.com
首页 > 其他好文 > 详细

Regular Expression Matching

时间:2015-03-30 22:52:12      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:

https://leetcode.com/problems/regular-expression-matching/

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

解题思路:

好吧,这题是做leetcode来最难的题目之一,我承认自己不会。只能看别人的解法,总结如下。

本题的难度主要在p中的*上,因为如果p当前字符是字母,可以直接和s匹配,判断是否继续,如果是‘.‘,也可以和s的任何字符匹配,判断是否继续。但如果p当前是*,就要看p的前一个字符在s中到底能代表多少个?事实上,这个很难有方法来确定,只能枚举,可能是1个、2个或3个。这个问题在最后参考网址的第一个里有例子。

所以本题的思路大体可以分为两大块。

1. p的下一个字符不是*。此时我们可以大胆判断s和p的当前字符是否匹配(这里包含了p当前为‘.‘的情况)。如果匹配,则s和p各前进一个字符,继续判断;如果不匹配,则可以直接返回false。

2. p的下一个字符是*。

2.1 s和p的当前字符不匹配,s不动,p跳过本字符和下一个‘*‘,继续判断。就像题目里最后一个例子。

2.2 s和p的当前字符匹配(这里包含了p当前为‘.‘的情况),假设为‘x‘。我们要看p的下一个*到底在s里代表了几个‘x‘?于是,s按步长为1往后移动,判断p跳过本字符和下一个‘*‘之后的部分,和s往后的部分是否匹配。只要有一个匹配的可能性,就可以返回true了。

当然,这里s往后移动的范围必须在连续的N个‘x‘内,或者p还是‘.‘。

public class Solution {
    public boolean isMatch(String s, String p) {
        return isMatchHelper(s, p, 0, 0);
    }
    
    public boolean isMatchHelper(String s, String p, int i, int j) {
        //p已经结束,此时s也结束,就返回true
        if(j >= p.length()){
            return i >= s.length();
        }
        //p到了最后一个字符,s必须也是最后一个字符,并且两者相等(此时p不可能是*,因为*总是和它的前一个字符一起被跳过的)
        if(j == p.length() - 1) {
            return (i == s.length() - 1) && (s.charAt(i) == p.charAt(j) || p.charAt(j) == ‘.‘);
        }
        //1.如果p的下一个字符不是*,如果s和p的当前字符能匹配,就继续往下,不匹配直接返回false
        if(p.charAt(j + 1) != ‘*‘) {
            //但是此时s已经匹配结束了,返回false
            if(i == s.length()) {
                return false;
            }
            if(p.charAt(j) == ‘.‘) {
                return isMatchHelper(s, p, i + 1, j + 1);
            }
            return s.charAt(i) == p.charAt(j) && isMatchHelper(s, p, i + 1, j + 1);
        }
        //2.如果p的下一个字符是*,即p.charAt(j + 1) == ‘*‘
        //2.1 如果s和p当前字符相等,或者p当前为.
        if(i < s.length() && (s.charAt(i) == p.charAt(j) || p.charAt(j) == ‘.‘)) {
            //在s.charAt(i) == p.charAt(j)的前提下,尝试s往后取1个、2个、3个...相同的字符,看后面只要匹配一种情况就可以
            while(i < s.length() && (s.charAt(i) == p.charAt(j) || p.charAt(j) == ‘.‘)) {
                if(isMatchHelper(s, p, i, j + 2)) {
                    return true;
                }
                i++;
            }
        }
        //2.2 p的下一个字符为*,且当前不为.,s和p当前字符不等,就直接跳过p的两个字符往后比较,比如题目中最后一个例子
        // if(s.charAt(i) != p.charAt(j) && p.charAt(j) != ‘.‘) {
            return isMatchHelper(s, p, i, j + 2);
        // }
    }
}

http://articles.leetcode.com/2011/09/regular-expression-matching.html

http://blog.csdn.net/fightforyourdream/article/details/17717873

http://blog.csdn.net/linhuanmars/article/details/21145563

Regular Expression Matching

标签:

原文地址:http://www.cnblogs.com/NickyYe/p/4376602.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!