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]; } }