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") →falseismatch ( "AA", "AA") →trueismatch ("AAA", "AA") →falseismatch ("AA", "A *") →trueismatch ("AA", ". *") →trueismatch ("AB", ". *") →true IsMatch ("AaB", "C*a*b") →true
The topic is to let us implement the regular expression in the * and. The matching function
. Match any one of the characters
* If a * is a whole, it means that there are 0 A or 1 A or 2 a or .... Any number of a
If it is. * can match 0 arbitrary characters or an arbitrary character or any number of any characters but these characters must be the same.
Ideas:
Start to feel with wildcard matching similar, later found not the same, wildcard matching inside * can be randomly matched, so when encountered after a *, the front of the * Can not tube.
Now this problem, * can only match duplicate characters, so you have to consider the range of multiple * representations, so the key to the problem is how many characters each x* represents.
It is easy to think of recursion, but after the completion of the recursion I submitted in the time of the various special circumstances can not pass, each time the special case add code, the result is increasingly longer, add to 70 lines still no AC. I silently know that my thinking must be a problem ...
Looking at the code of the great God, I finally know where the problem is.
Because I am a character each time a character to judge, so encountered * also need to judge a lot of * previous characters of the case.
But the great God every time for the P 2 characters for a group to judge the basis of * (p+1) = = ' * ' to distinguish between different situations, suddenly easy a lot.
Also, the code of the great God returns the answer when it encounters the return value is true, no longer recursion
classSolution { Public: BOOLMatchfirst (Const Char*s,Const Char*p) { return(*p = = *s | | (*p = ='.'&& *s! =' /')); }BOOLIsMatch (Const Char*s,Const Char*p) {if(*p = =' /')return(sb==' /';//Empty if(* (P +1) !='*') {//without * if(!matchfirst (S,P))return false; returnIsMatch (S +1, p +1); } Else{//Next:with A * if(IsMatch (s, p +2))return true;//try the length of 0 while(Matchfirst (S,P))//try all possible lengths if(IsMatch (++s, p +2))return true; }}};
Dynamic Planning methods:
Use dp[i][j] to indicate that S[0 ~ i-1] and p[0 ~ j-1] match, can match when True and vice versa is False
Then Dp[i][j] will only be true in the following 4 cases:
①dp[i-1][j-1] is true, and s[i-1] matches p[j-1]
②dp[i][j-1] is true, and p[j-1]== ' * '
③DP[I-1][J] is true, and p[j-1]== ' * ' and p[j-2] match s[i-1]
④dp[i][j-2] is true, and p[j-1]== ' * '
Boundary:
Dp[0][0] are empty and must be true
Dp[i][0] string is not empty, match string is empty, must be false
DP[0][J] string empty, match string non-empty, if p[j-1] = = ' * ' and dp[0][j-2] is true
The code is written in the way I refer to the great God.
classSolution { Public:BOOLIsMatch (Const Char*s,Const Char*p) {intm =strlen (s); intn =strlen (P); Vector<vector<BOOL>> DP (m+1, vector<BOOL> (n+1,false)); dp[0][0] =true; for(inti =1; I <= m; i++) {dp[i][0] =false; } for(intj =1; J <= N; J + +) {dp[0][J] = (p[j-1] =='*') && (J >=2) && dp[0][j-2];//The subscript of the J character in P is j-1, since it is starting from 0 } for(inti =1; I <= m; i++) { for(intj =1; J <= N; J + +) {Dp[i][j]= (dp[i-1][j-1] && (s[i-1] = = p[j-1] || p[j-1] =='.')) || (dp[i][j-1] && (p[j-1] =='*')) || (dp[i-1][J] && p[j-1] =='*'&& (J >=2) && s[i-1] = = p[j-2] || p[j-2] =='.')) || (J >=2) && dp[i][j-2] && (p[j-1] =='*')); } } returnDp[m][n]; }};
"Leetcode" Regular Expression Matching (Hard) ★