概述
我们得到了一个输入的REGEX和一个输入的字符串。雷格克斯可以有两个特殊字符
-
星号'*' - 星号匹配零个或多个字符。
-
问号'?' - 它匹配任何字符。
我们的目标是找出给定的输入字符串是否与重组词相匹配。
解释
Input String: aa
Regex Sring: aa
Output: true
Input String: ab
Regex Sring: a?
Output: true
Input String: aaaa
Regex Sring: *
Output: true
Input String: aa
Regex Sring: a
Output: false
以下是相同的递归解决方案
递归解决方案
在这个递归解决方案中
-
如果我们遇到了一个星形的*,那么我们有两种情况。我们忽略模式中的*字符,并转到模式中的下一个字符。另一种情况是,我们在输入字符串中移动一个字符,假设*至少匹配一个字符。基本上用**(inputIndex, patternIndex+1)和(inputIndex+1, patternIndex)**检查是否匹配。如果其中任何一个返回真,那么输入的字符串就与重码匹配。
-
如果我们遇到一个问号? 那么我们就用**(inputIndex+1, patternIndex+1)**简单地继续。
-
如果我们遇到一个简单的字符,那么我们就简单地在输入字符串和模式中进行,即我们进行**(inputIndex+1, patternIndex+1)**。
以下是该程序
package main
import "fmt"
func main() {
output := isMatch("aa", "aa")
fmt.Println(output)
output = isMatch("aaaa", "*")
fmt.Println(output)
output = isMatch("ab", "a?")
fmt.Println(output)
output = isMatch("adceb", "*a*b")
fmt.Println(output)
output = isMatch("aa", "a")
fmt.Println(output)
output = isMatch("mississippi", "m??*ss*?i*pi")
fmt.Println(output)
output = isMatch("acdcb", "a*c?b")
fmt.Println(output)
}
func isMatch(s string, p string) bool {
runeInputArray := []rune(s)
runePatternArray := []rune(p)
if len(runeInputArray) > 0 && len(runePatternArray) > 0 {
if runePatternArray[len(runePatternArray)-1] != '*' && runePatternArray[len(runePatternArray)-1] != '?' && runeInputArray[len(runeInputArray)-1] != runePatternArray[len(runePatternArray)-1] {
return false
}
}
return isMatchUtil([]rune(s), []rune(p), 0, 0, len([]rune(s)), len([]rune(p)))
}
func isMatchUtil(input, pattern []rune, inputIndex, patternIndex int, inputLength, patternLength int) bool {
if inputIndex == inputLength && patternIndex == patternLength {
return true
} else if patternIndex == patternLength {
return false
} else if inputIndex == inputLength {
if pattern[patternIndex] == '*' && restPatternStar(pattern, patternIndex+1, patternLength) {
return true
} else {
return false
}
}
if pattern[patternIndex] == '*' {
return isMatchUtil(input, pattern, inputIndex, patternIndex+1, inputLength, patternLength) ||
isMatchUtil(input, pattern, inputIndex+1, patternIndex, inputLength, patternLength)
}
if pattern[patternIndex] == '?' {
return isMatchUtil(input, pattern, inputIndex+1, patternIndex+1, inputLength, patternLength)
}
if inputIndex < inputLength {
if input[inputIndex] == pattern[patternIndex] {
return isMatchUtil(input, pattern, inputIndex+1, patternIndex+1, inputLength, patternLength)
} else {
return false
}
}
return false
}
func restPatternStar(pattern []rune, patternIndex int, patternLength int) bool {
for patternIndex < patternLength {
if pattern[patternIndex] != '*' {
return false
}
patternIndex++
}
return true
}
输出
true
true
true
true
false
false
false
动态程序解决方案
上面的程序不是一个优化的解决方案,因为子问题被反复解决了。这个问题也可以用DP来解决。
创建一个名为isMatchingMatrix 的二维矩阵,其中
isMatchingMatrix[i][j] 如果输入字符串中的第一个i字符与模式中的第一个j字符匹配,则为真。
If both input and pattern is empty
isMatchingMatrix[0][0] = true
If pattern is empty
isMatchingMatrix[i][0] = fasle
If the input string is empty
isMatchingMatrix[0][j] = isMatchingMatrix[0][j - 1] if pattern[j – 1] is '*'
以下是相同的程序。
package main
import "fmt"
func main() {
output := isMatch("aa", "aa")
fmt.Println(output)
output = isMatch("aaaa", "*")
fmt.Println(output)
output = isMatch("ab", "a?")
fmt.Println(output)
output = isMatch("adceb", "*a*b")
fmt.Println(output)
output = isMatch("aa", "a")
fmt.Println(output)
output = isMatch("mississippi", "m??*ss*?i*pi")
fmt.Println(output)
output = isMatch("acdcb", "a*c?b")
fmt.Println(output)
}
func isMatch(s string, p string) bool {
runeInput := []rune(s)
runePattern := []rune(p)
lenInput := len(runeInput)
lenPattern := len(runePattern)
isMatchingMatrix := make([][]bool, lenInput+1)
for i := range isMatchingMatrix {
isMatchingMatrix[i] = make([]bool, lenPattern+1)
}
isMatchingMatrix[0][0] = true
for i := 1; i < lenInput; i++ {
isMatchingMatrix[i][0] = false
}
if lenPattern > 0 {
if runePattern[0] == '*' {
isMatchingMatrix[0][1] = true
}
}
for j := 2; j <= lenPattern; j++ {
if runePattern[j-1] == '*' {
isMatchingMatrix[0][j] = isMatchingMatrix[0][j-1]
}
}
for i := 1; i <= lenInput; i++ {
for j := 1; j <= lenPattern; j++ {
if runePattern[j-1] == '*' {
isMatchingMatrix[i][j] = isMatchingMatrix[i-1][j] || isMatchingMatrix[i][j-1]
}
if runePattern[j-1] == '?' || runeInput[i-1] == runePattern[j-1] {
isMatchingMatrix[i][j] = isMatchingMatrix[i-1][j-1]
}
}
}
return isMatchingMatrix[lenInput][lenPattern]
}
输出
true
true
true
true
false
false
false