[leetcode] 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

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

思路1:递归。根据下一个字符是否是'*'分情况判断。

  1. 如果p的下一个字符不是'*',只需判断当前字符是否相等,或者p[cur]='.',递归处理s[1]和p[1];
  2. 如果是p的下一个'*',则当前s和p相等或者p='.'情况下,依次判断s[0...s.length]和p2]是否match;

思路2:自动机?有待研究。

思路3:DP。

递归代码:

public class Solution {
	public boolean isMatch(String s, String p) {
		if (s == null)
			return p == null;
		if (p == null)
			return s == null;

		int lenS = s.length();
		int lenP = p.length();

		if (lenP == 0)
			return lenS == 0;

		if (lenP == 1) {
			if (p.equals(s) || p.equals(".") && s.length() == 1) {
				return true;
			} else
				return false;
		}
		if (p.charAt(1) != '*') {
			if (s.length() > 0
					&& (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')) {
				return isMatch(s.substring(1), p.substring(1));
			}
			return false;
		} else {
			while (s.length() > 0
					&& (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')) {
				if (isMatch(s, p.substring(2)))
					return true;
				s = s.substring(1);
			}
                //don's skip this line, s is now "" return isMatch(s, p.substring(2)); } } public static void main(String[] args) { System.out.println(new Solution().isMatch("aa", "a")); System.out.println(new Solution().isMatch("aa", "aa")); System.out.println(new Solution().isMatch("aaa", "aa")); System.out.println(new Solution().isMatch("aa", "a*")); System.out.println(new Solution().isMatch("aa", ".*")); System.out.println(new Solution().isMatch("ab", ".*")); System.out.println(new Solution().isMatch("aab", "c*a*b")); System.out.println(new Solution().isMatch("", "")); System.out.println(new Solution().isMatch("abcdeff", ".*")); System.out.println(new Solution().isMatch("a", "ab*")); System.out.println(new Solution().isMatch("bb", ".bab")); } }

第二遍记录:

  注意递归终止条件的判断,null的情况,然后根据p的长度分情况讨论。

  注意有*时候的处理

public class Solution {
    public boolean isMatch(String s, String p) {
        if(s==null)
            return p==null;
        if(p==null)
            return s==null;
        int lenS=s.length();
        int lenP=p.length();
        if(lenP==0)
            return lenS==0;
        if(lenP==1){
            if(s.equals(p) || p.charAt(0)=='.'&& lenS==1)
                return true;
            else
                return false;
        }
        if(p.charAt(1)!='*'){
            if(lenS>0&&(p.charAt(0)==s.charAt(0)||p.charAt(0)=='.'))
                return isMatch(s.substring(1),p.substring(1));
            return false;
        }
        else{
            while(lenS>0 && (p.charAt(0)==s.charAt(0)||p.charAt(0)=='.')){
                if(isMatch(s,p.substring(2)))
                    return true;
                s=s.substring(1);
                lenS--;
            }
        //don't skip this line, s is now "".
return isMatch(s,p.substring(2)); } } }

第三遍:开始没往dp方向想,经某人指点。

public class Solution {
    public boolean isMatch(String s, String p) {
            int height = s.length(),width = p.length();
            boolean[][] dp = new boolean[height + 1][width + 1];
            dp[0][0] = true;
            for(int i = 1; i <= width; i++){
                if(p.charAt(i - 1) == '*') dp[0][i] = dp[0][i - 2];
            }
            for(int i = 1; i <= height; i++){
                for(int j = 1; j <= width; j++){
                    char sChar = s.charAt(i - 1);                
                    char pChar = p.charAt(j - 1);
                    if(sChar == pChar || pChar == '.'){
                        dp[i][j] = dp[i - 1][j - 1];
                    }else if(pChar == '*'){
                        if(sChar != p.charAt(j - 2) && p.charAt(j - 2) != '.'){
                            dp[i][j] = dp[i][j - 2];
                        }else{
                            dp[i][j] =  dp[i][j - 2] | dp[i - 1][j];
                        }
                    }
                }
            }
            return dp[height][width];
        }
}

参考:

http://www.programcreek.com/2012/12/leetcode-regular-expression-matching-in-java/

http://fisherlei.blogspot.com/2013/01/leetcode-wildcard-matching.html

http://leetcodenotes.wordpress.com/2013/08/25/leetcode-regular-expression-matching/

原文地址:https://www.cnblogs.com/jdflyfly/p/3810681.html