• [LeetCode#10]Regular Expression Matching


    Problem:

    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

    Analysis:

    This question is really not hard if you use DFS way to match the string. (not dynamic programming!)
    The most challengeing part is to clearly differentiate different cases.
    Basic idea: (recursive)
    1. iff p.charAt(1) = '*', it means we can use p.charAt(0) to match zero or more characters(susscive) in the s. Then continue to compare the remaining part.
    2. iff p.charAt(1) != '*', it means we can don't need to care p.charAt(1), we can soly compare the p.charAt(0) and s.charAt(0). The key point is that if p.charAt(1) = '*', it can affect the match of p.charAt(0), thus we must treat it carefully. 
    
    Like other matching problems, use s to match aginst p!!!! It is better for us to write the checking condition based on p. 
    Detail:
    1. base case (when p is "") <this is where a success match ends with>
    It means all p's characters have already been matched.
    Iff s is also "", it means p and s perfectly matched. Otherwise, we return false for this branch.
    ----------------------------------------------------------------------    
    if (p.length() == 0)
        return s.length() == 0;
    ----------------------------------------------------------------------    
    Note: this check is very common for following situations, p and s must perfectly match with each other. 
    
    
    2. when p has only one character.
    iff s is null, return false,
    iff s is not null, we check if s.charAt(0) == p.charAt(0) or p.charAt(0) = '.'.
        iff not we return false;
        iff yes, we continue to compare remaining part.
    ----------------------------------------------------------------------    
    if (p.length() == 1) {
        if (s.length() == 0)
            return false;
        else if (p.charAt(0) != '.' && p.charAt(0) != s.charAt(0))
            return false;
        else 
            return isMatch(s.substring(1), p.substring(1));
    }
    ----------------------------------------------------------------------    
    Note: you may notice that we do not have following logic:
    if (s.length () > 1)
        return false;
    This case would finally be hanlded at "return isMatch(s.substring(1), p.substring(1));". The reason why do not write in that way is to use the power of recursive and not to break it is code structure.
    
    
    3. when p has more than one character.
    3.1 p.charAt(1) != '*'
        Following the same checking in 2.
    Note: we don't bother the check p.charAt(1) = s.charAt(1) at this step.
    ----------------------------------------------------------------------    
    if (p.charAt(1) != '*') {
        if (s.length() < 1)
            return false;
        if (p.charAt(0) != '.' && p.charAt(0) != s.charAt(0))
            return false;
        else 
            return isMatch(s.substring(1), p.substring(1));
    }
    ----------------------------------------------------------------------    
    
    3.2 p.charAt(1) == '*'
    3.2.1 we use the case: '*' represent no pre character(this is the hardest case using other method)
       if (isMatch(s, p.substring(2)))
                    return true;
    
    3.2.2 '*' represent one (more) pre charcter (many times)
    int index = 0;
    while (index < s.length() && (s.charAt(index) == p.charAt(0) || p.charAt(0) == '.' )) {
        if (isMatch(s.substring(index+1), p.substring(2)))
            return true;
            index++;
        }
    return false;
    
    Note: '.' can represent as many characters as possible in s.

    Solution:

    public class Solution {
        public boolean isMatch(String s, String p) {
            if (p.length() == 0)
                return s.length() == 0;
            if (p.length() == 1) {
                if (s.length() == 0)
                    return false;
                else if (p.charAt(0) != '.' && p.charAt(0) != s.charAt(0))
                    return false;
                else 
                    return isMatch(s.substring(1), p.substring(1));
            }
            //at least two characters left at p
            if (p.charAt(1) != '*') {
                if (s.length() < 1)
                    return false;
                if (p.charAt(0) != '.' && p.charAt(0) != s.charAt(0))
                    return false;
                else 
                    return isMatch(s.substring(1), p.substring(1));
            } else{
                if (isMatch(s, p.substring(2)))
                    return true;
                int index = 0;
                while (index < s.length() && (s.charAt(index) == p.charAt(0) || p.charAt(0) == '.' )) {
                    if (isMatch(s.substring(index+1), p.substring(2)))
                        return true;
                    index++;
                }
                return false;
            }
        }
    }
  • 相关阅读:
    BZOJ_2002_[Hnoi2010]Bounce 弹飞绵羊_LCT
    BZOJ_4154_[Ipsc2015]Generating Synergy_KDTree
    BZOJ_2801_[Poi2012]Minimalist Security_dfs树+特判+乱搞
    BZOJ_3123_[Sdoi2013]森林_主席树+启发式合并
    2019集训队作业做题实况[1](1-30):
    牛客挑战赛33 F 淳平的形态形成场(无向图计数,EGF,多项式求逆)
    【NOIP2019模拟2019.10.07】果实摘取 (约瑟夫环、Mobius反演、类欧、Stern-Brocot Tree)
    CodeChef Max-digit Tree(动态规划)
    骚操作:c++如何用goto便捷地写人工栈?
    Comet OJ
  • 原文地址:https://www.cnblogs.com/airwindow/p/4783022.html
Copyright © 2020-2023  润新知