---
# System prepended metadata

title: String Matching (Dynamic Programming)

---

# String Matching (Dynamic Programming)

leetcode problem 44: Wildcard Matching

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

Ex 1:
Input: s = "adceb", p = "\*a*b"
Output: true

Ex 2:
Input: s = "acdcb", p = "a*c?b"
Output: false

## 解法
![](https://i.imgur.com/KcEBqAJ.jpg)
![](https://i.imgur.com/Bcz2Bn5.jpg)
![](https://i.imgur.com/TdJ2WL5.jpg)

## Code


### leetcode problem 44

```
class Solution {
public:
    bool isMatch(string s, string p) {
        string p1 = "";
        char c = '0';
        for(int i=0;i<p.size();++i){
            if(p[i] == '*' && c == '*'){
                c = p[i];
                continue;
            }
            p1 += p[i];
            c = p[i];
        }
        
        int row = s.size()+1;
        int col = p1.size()+1;
        bool dp[row][col];
        for(int i=0;i<row;++i){
            for(int j=0;j<col;++j){
                dp[i][j] = 0;
            }
        }
        dp[0][0] = 1;
        
        string s1 = " " + s;
        p1 = " " + p1;
        
        if(p1[1] == '*'){
            dp[0][1] = 1;
        }
        
        for(int i=1;i<row;++i){
            for(int j=1;j<col;++j){
                if(s1[i] == p1[j] || p1[j] == '?'){
                    dp[i][j] = dp[i-1][j-1];
                }
                
                if(p1[j] == '*'){
                    dp[i][j] = dp[i-1][j] || dp[i][j-1];
                }
            }
        }
        
        return dp[row-1][col-1];
        
    }
};
```

### leetcode problem 10

星號變成只代表前一個字元可以出現0次或重複次，另外'.'和'?'意義相同。解法差不多，只需稍作修改即可。要注意的地方是，星號代表前一個字元出現一次以上時，除了要dp[i-1][j]成立，還要現在這個字元和\*前的字元相同。整個判斷式就會變成:
```
(((s1[i] == p1[j-1]) || (p1[j-1] == '.')) && dp[i-1][j])
```
另外，初始化的地方也要特別注意。不只要將dp[0][0]設為1，星號出現的那格要設為和前兩格相同的值。如下:
```
dp[0][0] = 1;
for(int j=2;j<col;++j){
    if(p1[j] == '*'){
        dp[0][j] = dp[0][j-2];
    }
}
```
因為星號可以代表前一個字元出現0次，也就是不出現。因此"a*"是match空字串的。"a\*b*"也是match ""的。但"a\*bc*"就不會match ""了。


```
class Solution {
public:
    bool isMatch(string s, string p) {
        string p1 = "";
        char c = '0';
        for(int i=0;i<p.size();++i){
            if(p[i] == '*' && c == '*'){
                c = p[i];
                continue;
            }
            p1 += p[i];
            c = p[i];
        }
        
        int row = s.size() + 1;
        int col = p1.size() + 1;
        bool dp[row][col];
        for(int i=0;i<row;++i){
            for(int j=0;j<col;++j){
                dp[i][j] = 0;
            }
        }
        
        // padding
        string s1 = " " + s;
        p1 = " " + p1;
        
        dp[0][0] = 1;
        for(int j=2;j<col;++j){
            if(p1[j] == '*'){
                dp[0][j] = dp[0][j-2];
            }
        }
        
        for(int i=1;i<row;++i){
            for(int j=1;j<col;++j){
                if(s1[i] == p1[j] || p1[j] == '.'){
                    dp[i][j] = dp[i-1][j-1];
                }
                
                if(p1[j] == '*'){
                    // more than 1 chars || 1 char || 0 char
                    dp[i][j] = (((s1[i] == p1[j-1]) || (p1[j-1] == '.')) && dp[i-1][j]) || dp[i][j-1] || dp[i][j-2];
                    
                }
            }
        }
        
        return dp[row-1][col-1];
    }
};
```