正则表达式匹配——动态规划

89 阅读1分钟

image.png

代码动态规划:

  1. dp[i][j] 表示 s 的前 i 个字符与 p 的前 j 个字符是否匹配
  2. 当前字符匹配或当前字符为 点 则状态转移:dp[i][j] = dp[i-1][j-1]
  3. 当前若为星号,则需要与前一个字符作为整体考虑
  4. 若整体为 0 则状态转移:dp[i][j] = dp[i][j-2]
  5. 若整体为1,为2,为3等等,要考虑的状态转移太多了,
  6. 所以我们可以反过来考虑 s ,我们现在已知的状态有 之前行 以及 当前行中在当前列之前 的状态
  7. 所以当组合整体为 n 且不为 0 的时候,状态转移:dp[i][j] = dp[i-1][j] ,当然在进行此状态转移的时候要满足当前字符与星号复制的字符相同
  8. 最后返回 dp[ss][pp] 即可
func isMatch(s string, p string) bool {
    ss := len(s)
    pp := len(p)
    dp := make([][]bool, ss+1)
    for i := range dp {
        dp[i] = make([]bool, pp+1)
    }
    dp[0][0] = true
    for i := 1; i < pp; i += 2 {
        if p[i] != '*' {
            break
        }
        dp[0][i+1] = true 
    }
    for i := 1; i <= ss; i++ {
        for j := 1; j <= pp; j++ {
            if p[j-1] == s[i-1] || p[j-1] == '.' {
                dp[i][j] = dp[i-1][j-1]
            }else if p[j-1] == '*' {
                dp[i][j] = dp[i][j-2] || ( (p[j-2] == s[i-1] || p[j-2] == '.') && dp[i-1][j] ) //优化代码
                // dp[i][j] = dp[i][j-1] || dp[i][j-2] || ( (p[j-2] == s[i-1] || p[j-2] == '.') && (dp[i-1][j-1] || dp[i-1][j]) ) 
            }
        }
    }
    return dp[ss][pp]
}