Implement regular expression matching with support for'.'and'*'.html
'.' 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/java
思路1:遞歸。根據下一個字符是不是'*'分狀況判斷。express
思路2:自動機?有待研究。wordpress
思路3:DP。this
遞歸代碼:spa
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")); } }
第二遍記錄:prototype
注意遞歸終止條件的判斷,null的狀況,而後根據p的長度分狀況討論。code
注意有*時候的處理htm
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方向想,經某人指點。blog
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/