Leetcode10 dynamic programming realizes simple regular matching

topic:

Realize simple regular matching


Solution: dynamic programming

Characters: .and a~z.
Quantity:, *which is a whole with the character before it.

a*The structure of the specific implementation of several a's function rules is very complicated, it is impossible to write if directly, so you need to enumerate all the situations (the role of 0~n a), and one of the matches is successful even if it is successful.

  • Select state
    dp[i][j]represents s[0~i]the p[0~j]match.
  • The state transition equation
    dp [i] [j] = {dp [i − 1] [j − 1] p [j]! = ′ ∗ ′ and check (s [i], p [j]) falsep [j]! = ′ ∗ ′ and! check (s [i], p [j]) dp [i] [j − 2] p [j] = = ′ ∗ ′ and! check (s [i], p [j − 1 ]) Play 0 dp [i] [j − 2] ∣ ∣ play 1 dp [i − 1] [j − 2] ∣ ∣ play multiple dp [i − 1] [j] p [j] = = ′ ∗ ′ and check (s [i], p [j − 1]) dp[i][j] = \begin{cases} dp[i-1][j-1] & p[j]!=' *'and check(s[i],p[j]) \\ false & p[j]!='*' and! check(s[i],p[j]) \\ dp[i][j -2] & p[j]=='*'and!check(s[i],p[j-1]) \\ play 0 dp[i][j-2] || play 1 dp[ i-1][j-2] || Play multiple dp[i-1][j] & p[j]=='*' and check(s[i],p[j-1]) \end {cases}dp[i][j]=dp[i1][j1]falsedp[i][j2]Hair waving 0 th D P [ I ] [ J2 ] | | hair waving . 1 th D P [ I1][j2 ] | | hair waving plurality th D P [ I1][j]p[j]!= Andcheck(s[i],p[j])p[j]!= And!check(s[i],p[j])p[j]== And!check(s[i],p[j1])p[j]== Andcheck(s[i],p[j1])
    0<=i<s.length(), 0<=j<p.length()
    Where the check function is:
bool check(char a, char b){
    
    
        if(a=='.' || b=='.') return true;
        else return a==b;
    }

So far there are still two problems that need to be solved:

  1. If you enter an empty string, an error will occur when opening the array.
    The matching of empty strings and the matching of normal strings use the same set of methods, and one character can be added at the beginning or the end ?. That is, let the input string length be at least 1.
  2. Negative subscripts (boundaries) may appear in the state transition equation.
    For guarantee i,j>=1, the characters of string can be numbered starting from 1. Combining with the first question, you can insert a "starting symbol" at the beginning of the string uniformly.
  • Boundary
    Row 0, column 0 needs to be initialized:
    dp[0][0] = true
    dp[i][0] = false, 1<=i<s.length()

1 <= j <p. Length () dp [0] [j] = {dp [0] [j − 2] p [j] = = ′ ∗ ′ (j equal to ∗ must be an even number) falsep [j] ! = ′ ∗ ′ 1<=j<p.length() \\ dp[0][j] = \begin{cases} dp[0][j-2] & p[j]=='*'( J equal to * must be an even number) \\ false & p[j]!='*' \end{cases} 1<=j<p.length()dp[0][j]={ dp[0][j2]falsep[j]==' (LikeinThe j a set is an even number )p[j]!=

  • The processing sequence
    involves the points on the left, above, and above the current point. The processing sequence is from top to bottom and from left to right.
class Solution {
    
    
public:
    bool isMatch(string s, string p) {
    
    
        s.insert(s.begin(), '?');
        p.insert(p.begin(), '?');
        int slen=s.length(), plen=p.length();
        //初始化
        bool dp[slen][plen]={
    
    };
        dp[0][0] = true;
        for(int j=1; j<plen; j++){
    
    
            if(p[j]=='*') dp[0][j] = dp[0][j-2];
        }
        //填表
        for(int j=1; j<plen; j++){
    
    
            for(int i=1; i<slen; i++){
    
    
                if(p[j]=='*'){
    
    
                    if(check(s[i], p[j-1])) dp[i][j] = dp[i][j-2]||dp[i-1][j-2]||dp[i-1][j];
                    else dp[i][j] = dp[i][j-2];
                }
                else{
    
    
                    if(check(s[i], p[j])) dp[i][j] = dp[i-1][j-1];
                    else dp[i][j] = false;
                }
            }
        }
        return dp[slen-1][plen-1];
    }

    bool check(char a, char b){
    
    
        if(a=='.' || b=='.') return true;
        else return a==b;
    }
};

Guess you like

Origin blog.csdn.net/sinat_37517996/article/details/104800896