I spent a lot of time digesting this subject on Leetcode.
The topic is as follows:
Implements the matching of two string s,t, where the T string
'. ' can match any one character.
' * ' can act as 0 or more characters in front of one.
Match result to overwrite entire string
A few 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
For example, in the last example, C*a*b can match AaB to show that the first * acts as 0 C and the second * acts as two A.
There are two more common solutions to this problem: recursion and motion regulation. I'll take a brief analysis of the two methods below.
Recursive method
One difficulty with this problem is how to deal with the symbol "*" in the T-string, and sometimes it is not possible to write the code clearly. We can intuitively think that when the "*" appears, the "*" can act as 0, 1, 2 ... The preceding character, which acts as a procedure that also needs to satisfy the condition (s[i]==p[0]) or (p[i]== '. ' && s[i]!= '). We compare each possibility with the S string once, and if there is one that matches the success, that is the match.
If the current match symbol in the T string is not the symbol "*" It would be much better to do so, we will directly judge S[i]==p[0] or p[0]== '. ', if the match is successful, then the next match can be made.
The reference code is as follows: (Refer to others)
//Recursive methodBOOLIsMatch (stringSstringP) {if(P.empty ())returnS.empty ();//p[1] not * if(p[1]!=' * ') {return(s[0]==p[0] || (p[0]=='. '&&!s.empty ()) && IsMatch (S.substr (1), P.substr (1)); }//p[1] Yes * inti =0; for(; s[i]==p[0] || (p[0]=='. '&& i<s.size ()); ++i) {//* can act as 0, 1, 2 ... p[0] But match conditions must be met if(IsMatch (S.substr (i), P.substr (2)) )return true; }//p[1] Yes * but p[0]! = S[i] returnIsMatch (S.substr (i), P.substr (2));}
Dynamic Programming method
People who are more familiar with dynamic planning may be more comfortable with this approach.
We provide a two-dimensional set of f[i][j] whose representation string s[0..i-1] can be matched successfully with t[0...j-1] and we can quickly get a dynamic programming transfer equation
- When t[j-1]!= ' * ' f[i][j] = f[i-1][j-1] && (s[i-1] = = T[j-1])
This is a good understanding, s[i-1] and t[j-1] if the same, then its s[0...i-2] to t[0...j-2] can still match success, then the two strings are the match success.
- When t[j-1]== ' * ' t[j-1] can act as 0 or more t[j-2], as long as any one of the following two conditions is met, F[i][j] result is true
- T[J-1] acts as 0 T[j-2]: f[i][j] = f[i][j-2]
- T[j-1] as 1 or more t[j-2]: f[i][j] = (s[i-1] = = P[j-2] | | '. ' = = P[j-2]) && F[i-1][j]
The f[i-1][j in the equations of motion] contains the t[j-1] act as 2, 3 ... Multiple t[j-2], and we have calculated and saved the results in the process of moving the rules.
The reference code is as follows: (Refer to others)
BOOLIsMatch (stringSstringP) {intm = S.size (), n = p.size (); vector<vector<bool>>F (M +1, vector<bool>(n +1,false)); f[0][0] =true;//empty string matched successfully with empty string for(inti =1; I <= m; i++)the//s string matches the empty string with the result of falsef[i][0] =false;//p[0..j-1] can match the empty string to meet the p[j-1]== ' * ' and p[0..j-3] can match the empty string for(intj =1; J <= N; J + +) f[0][J] = j >1&&' * '= = P[j-1] && f[0][j-2]; for(inti =1; I <= m; i++) for(intj =1; J <= N; J + +)if(P[j-1] !=' * ') F[i][j] = f[i-1][j-1] && (S[i-1] = = P[j-1] ||'. '= = P[j-1]);ElseF[I][J] = f[i][j-2] || (S[i-1] = = P[j-2] ||'. '= = P[j-2]) && F[i-1][J];returnF[m][n];}
Two different ways of thinking, which have the same part, can solve the problem, record for later review.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Leetcode:regular Expression Matching