zoukankan      html  css  js  c++  java
  • [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/

  • 相关阅读:
    JavaScript 预解析
    JavaScript 作用域
    JavaScript 函数
    SlidesJS
    1. Skippr
    HTML5 模拟现实物理效果
    实现各种 CSS3 文本动画效果
    表单填写进度提示效果
    HTML5 WebGL 实现逼真的云朵效果
    【原创】bootstrap框架的学习 第八课 -[bootstrap表单]
  • 原文地址:https://www.cnblogs.com/jdflyfly/p/3810681.html
Copyright © 2011-2022 走看看