Sword finger Offer 19. Detailed problem solution of regular expression matching

Sword finger Offer 19. Regular expression matching

subject

Please implement a function to match regular expressions containing '.' and '*'. The character '.' in the mode indicates any character, while '*' indicates that the character before it can appear any time (including 0 times). In this question, matching means that all characters of the string match the whole pattern. For example, the string "aaa" matches the patterns "a.a" and "abaca", but not "aa.a" and "ab*a".

Example 1:
Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" cannot match "aa" the entire string.

Example 2:
Input:
s = "aa"
p = "a*"
Output: true
Explanation: because '*' means that zero or more preceding elements can be matched, the preceding element here is' a '. Therefore, the string "aa" can be regarded as' a 'repeated once.

Example 3:
Input:
s = "ab"
p = "."
Output: true
Explanation: "." means that it can match zero or more ('*') arbitrary characters ('.').

Example 4:
Input:
s = "aab"
p = "cab"
Output: true
Explanation: because '*' represents zero or more, here 'c' is 0, and 'a' is repeated once. Therefore, the string "aab" can be matched.

Example 5:
Input:
s = "mississippi"
p = "misisp*."
Output: false

s may be empty and contain only lowercase letters from a-z.
p may be empty and contain only lowercase letters from a-z and the characters. And *, with no consecutive '*'.
Note: this question is the same as question 10 of the main station: https://leetcode-cn.com/problems/regular-expression-matching/

Source: LeetCode
Link: https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof

Problem solving ideas

Method 1: "cheating"
Directly use the function matches provided by java to judge whether the string matches the regular expression. Actually, the static method of Pattern is called.

Law 2: violence recursion
When writing, you should think clearly and judge whether the given regular expression is empty. When both p and s are empty, it proves that the matching is successful. After excluding this situation, judge whether the first character of S and p matches.
When the next character of p is * look at the matching result of the first character in front.
Mismatch, p moves back two bits during recursion, and s remains unchanged.
Match, then s moves back one bit and p remains unchanged during recursion.
If the first characters of s and p are equal, the remaining strings are recursive.

Method 3: dynamic programming
Dynamic programming should first find laws and transfer equations.
If you look at the previous solution, you can get:
f[0][0] = true when both string and expression are empty
f[i][j] = f[i-1][j-1]
When the current character does not match, but the next digit is *, f[i][j] = f[i][j-2]
When the current character matches and the next digit is *, f[i][j] = f[i-1][j]

java code

//FA Yi
class Solution {
    public boolean isMatch(String s, String p) {
        return s.matches(p);//Matches checks whether the string matches the given regular expression
    }
}
//Method II
class Solution {
    public boolean isMatch(String s, String p) {
    //If p is empty and s is also empty, the matching is successful
    if (p.isEmpty()){
        return s.isEmpty();
    }
    //Determine whether the first character of s and p matches
    boolean headMatched = !s.isEmpty() && (s.charAt(0)==p.charAt(0)||p.charAt(0)=='.');
    if (p.length()>=2 && p.charAt(1)=='*'){//If the next element of the first element of p is*
        return isMatch(s,p.substring(2)) || (headMatched&&isMatch(s.substring(1),p));
    }
    else if (headMatched){//If the first characters of s and p are equal
        return isMatch(s.substring(1),p.substring(1));
    }
    else {
        return false;
    }
  }
}
//Method three
class Solution {
    public boolean isMatch(String s, String p) {
        int lens = s.length();
        int lenp = p.length();
        //Initialize dynamic programming matrix
        boolean[][] dp = new boolean[lens+1][lenp+1];
        dp[0][0] = true;//Both are space-time matching
        for(int j = 2; j < lenp+1; j += 2){//initialization
            dp[0][j] = dp[0][j - 2] && p.charAt(j - 1) == '*';
        }
            
        for(int i = 1; i < lens+1; i++) {
            for(int j = 1; j < lenp+1; j++) {
                if(p.charAt(j - 1) == '*'){
                    dp[i][j] = dp[i][j - 2] || dp[i - 1][j] && (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.');
                }
                else{
                    dp[i][j] = dp[i - 1][j - 1] && (p.charAt(j - 1) == '.' || s.charAt(i - 1) == p.charAt(j - 1));
                }                    
            }
        }
        return dp[lens][lenp];
    }
 } 
 

Tags: Java leetcode Dynamic Programming

Posted on Sat, 23 Oct 2021 16:14:25 -0400 by formxshape