1. 程式人生 > 實用技巧 >每日總結

每日總結

劍指 Offer 19. 正則表示式匹配

地址:劍指 Offer 19. 正則表示式匹配

問題描述:

請實現一個函式用來匹配包含'. '和''的正則表示式。模式中的字元'.'表示任意一個字元,而''表示它前面的字元可以出現任意次(含0次)。在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串"aaa"與模式"a.a"和"abaca"匹配,但與"aa.a"和"ab*a"均不匹配。

示例 1:

輸入:
s = "aa"
p = "a"
輸出: false
解釋: "a" 無法匹配 "aa" 整個字串。
示例 2:

輸入:
s = "aa"
p = "a"
輸出: true
解釋: 因為 '
' 代表可以匹配零個或多個前面的那一個元素, 在這裡前面的元素就是 'a'。因此,字串 "aa" 可被視為 'a' 重複了一次。
示例 3:

輸入:
s = "ab"
p = "."
輸出: true
解釋: ".
" 表示可匹配零個或多個('*')任意字元('.')。
示例 4:

輸入:
s = "aab"
p = "cab"
輸出: true
解釋: 因為 '*' 表示零個或多個,這裡 'c' 為 0 個, 'a' 被重複一次。因此可以匹配字串 "aab"。
示例 5:

輸入:
s = "mississippi"
p = "misisp*."
輸出: false
s 可能為空,且只包含從 a-z 的小寫字母。
p 可能為空,且只包含從 a-z 的小寫字母以及字元 . 和 ,無連續的 ''。
注意:本題與主站 10 題相同:https://leetcode-cn.com/problems/regular-expression-matching/

import util.control.Breaks._
object Solution {
    def isMatch(s: String, p: String): Boolean = {
        val sLen = s.length
        val pLen = p.length
        val newS = ' ' + s
        val newP = ' ' + p
        val dp = Array.fill(sLen+1, pLen+1)(false)
        //val dp = Array.ofDim[Boolean](sLen+1, pLen+1)
        dp(0)(0) = true

        for (i <- 0 to sLen) {
            for (j <- 1 to pLen){
                breakable{
                    if (j + 1 <= pLen && newP(j+1) == '*') {
                        break()
                    }

                    if (i > 0 && newP(j) != '*') {
                        dp(i)(j) = dp(i-1)(j-1) && (newS(i) == newP(j) || newP(j) == '.')
                    } else if (newP(j) == '*') {
                        //println("--------------------------------------------")
                        //println("i: " + i +" ,j: " + j)
                        //println("dp(i)(j-2): " + dp(i)(j-2))
                        if (i > 0) println("dp(i-1)(j): " + dp(i-1)(j) + " ,newS(i): " + newS(i) + " ,newP(j-1): " + newP(j-1))
                        //這裡dp(i-1)(j) 是按照01揹包情況處理
                        dp(i)(j) = (dp(i)(j-2)) || (i > 0 && dp(i-1)(j) && (newS(i) == newP(j-1) || newP(j-1) == '.'))
                        //println("dp(i)(j): " + dp(i)(j))
                    }
                }
            }
        }
        return dp(sLen)(pLen)
    }
}
func isMatch(s string, p string) bool {
    sLen := len(s)
    pLen := len(p)
    s = " " + s
    p = " " + p
    
    dp := make([][]bool, sLen+1)
    for i := 0; i < len(dp); i++ {
        dp[i] = make([]bool, pLen+1)
    }
    dp[0][0] = true

    for i := 0; i <= sLen; i++ {
        for j := 1; j <= pLen; j++ {
            if j + 1 <= pLen && p[j+1] == '*' {
                continue
            }

            if i > 0 && p[j] != '*' {
                dp[i][j] = dp[i-1][j-1] && (s[i] == p[j] || p[j] == '.')
            } else if p[j] == '*' {
                dp[i][j] = dp[i][j-2] || (i > 0 && dp[i-1][j] && (s[i] == p[j-1] || p[j-1] == '.'))
            }
        }
    }

    return dp[sLen][pLen]
}