/* 动态规划 */ package main import ( "fmt" "strings" ) // 判断字符是否为数字或字母 func isNumOrChar(b byte) bool { return (b >= '0' && b <= '9') || (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') } // 不区分大小写的字符比较 func equalIgnoreCase(a, b byte) bool { return strings.ToLower(string(a)) == strings.ToLower(string(b)) } // 检查通配符 s 是否匹配目标字符串 p func check(s, p string) bool { m, n := len(s), len(p) // dp[i][j] 表示 s[:i] 是否匹配 p[:j] dp := make([][]bool, m+1) for i := range dp { dp[i] = make([]bool, n+1) } // 空模式匹配空字符串 dp[0][0] = true // 处理 s 开头的 '*' 可以匹配空字符串 for i := 1; i <= m; i++ { if s[i-1] == '*' { dp[i][0] = dp[i-1][0] } else { break // '*' 连续才有意义 } } // 填充 DP 表 for i := 1; i <= m; i++ { for j := 0; j <= n; j++ { if s[i-1] == '*' { // '*' 匹配 0 个:dp[i-1][j] // '*' 匹配多个:dp[i][j-1](如果 j>0) dp[i][j] = dp[i-1][j] if j > 0 { dp[i][j] = dp[i][j] || dp[i][j-1] } } else if s[i-1] == '?' { // '?' 必须匹配一个数字或字母 if j > 0 && isNumOrChar(p[j-1]) { dp[i][j] = dp[i-1][j-1] } } else { // 普通字符 if j > 0 { if isNumOrChar(s[i-1]) { // 字母:不区分大小写匹配 dp[i][j] = dp[i-1][j-1] && equalIgnoreCase(s[i-1], p[j-1]) } else { // 其他字符:精确匹配 dp[i][j] = dp[i-1][j-1] && (s[i-1] == p[j-1]) } } } } } return dp[m][n] } func main() { var s, p string fmt.Scanf("%s", &s) fmt.Scanf("%s", &p) // 注意:我们不提前转小写,因为在 equalIgnoreCase 中处理 result := check(s, p) if result { fmt.Println("true") } else { fmt.Println("false") } }