The sword refers to Offer-Question 19 (Java Edition): Regular Expression Matching

Reference from: "Sword Pointing Offer - Famous Enterprise Interviewer Talking About Typical Programming Questions"

Question : Regular Expression Matching
Please implement a function to match a regular expression containing '.' and '*'. The character '.' in the pattern means any character, and '*' means that the character preceding it can appear any number of times (including 0). In this question, match means that all characters of the string match the entire pattern. For example, the string "aaa" matches the patterns "aa" and "ab*ac*a", but neither "aa.a" nor "ab*a".

Main idea :
There are four cases:
1. The current character of the string does not match the current character of the pattern: return false.
2. The current character of the pattern is '.' or the same as the current character of the string: continue to match the remaining string and pattern.
3. The next character of the pattern is '*' and the current character matches, there are two options:
1) The string does not move; the pattern is moved 2 characters backward (equivalent to ignoring '*' and the characters before it, because '*' can match 0 characters).
2) The string is shifted back by 1 character; the pattern can remain the same, or the pattern can be shifted back by 2 characters.
4. If the next character of the pattern is '*' and the current character does not match, the string does not move, and the pattern moves backward by 2 characters.

Key point : '*' can match 0 or more characters

Time complexity : O(n)

public class RegularExpression
{
    private static char[] str;
    private static char[] pattern;

    public static void main(String[] args)
    {
        String inStr = "aaa";
        String inPattern = "aa*";
        String inStr1 = "aaa";
        String inPattern1 = "aa.a";
        boolean result1 = match(inStr.toCharArray(), inPattern.toCharArray()); //true
        boolean result2 = match(inStr1.toCharArray(), inPattern1.toCharArray()); //false
        System.out.println(result1);
        System.out.println(result2);
    }

    private static boolean match(char[] inStr, char[] inPattern)
    {
        if (inStr == null || inPattern == null) return false;
        str = inStr;
        pattern = inPattern;
        return matchRegular(0, 0);
    }

    private static boolean matchRegular(int strIndex, int patternIndex)
    {
        //字符和模式全部匹配
        if (str.length == strIndex && pattern.length == patternIndex)
        {
            return true;
        }
        if ((str.length != strIndex && pattern.length == patternIndex))
        {
            return false;
        }
        //模式的下一个字符是‘*’
        if (patternIndex < pattern.length - 1 && pattern[patternIndex + 1] == '*')
        {
            //当前字符匹配
            if (strIndex < str.length && (pattern[patternIndex] == str[strIndex]
                    || pattern[patternIndex] == '.'))
            {
                return matchRegular(strIndex + 1, patternIndex + 2)  //字符串和模式都移动
                        || matchRegular(strIndex + 1, patternIndex)  //字符串移动,模式不动
                        || matchRegular(strIndex, patternIndex + 2);  //字符串不动,模式移动
            } else
            {
                return matchRegular(strIndex, patternIndex + 2); //字符串不动,模式移动
            }
        }
        //当前字符和模式的字符匹配
        if (strIndex < str.length && (pattern[patternIndex] == str[strIndex]
                || pattern[patternIndex] == '.'))
        {
            return matchRegular(strIndex + 1, patternIndex + 1);  //模式和字符串都移动
        }
        return false;
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325982225&siteId=291194637