通配符匹配(Wildcard Matching)的进阶版:支持多模式匹配的通配符匹配
字数 1783 2025-11-29 14:15:07

通配符匹配(Wildcard Matching)的进阶版:支持多模式匹配的通配符匹配

题目描述
给定一个输入字符串 s 和一组模式 patterns,每个模式可以包含普通字符、通配符 ?(匹配任意单个字符)和 *(匹配任意字符序列,包括空序列)。判断字符串 s 是否能被 patterns 中的任意一个模式完全匹配。注意:匹配必须是完整的,即整个字符串 s 需被某个模式完全覆盖。

示例
输入:s = "abcd", patterns = ["a*c?", "b*d", "a?d"]
输出:true
解释:模式 "a*c?" 可以匹配 "abcd"a 匹配 a* 匹配 bcc? 匹配 cd)。


解题过程
此问题可转化为对每个模式单独判断是否匹配 s,只要有一个模式匹配成功即返回 true。核心是扩展经典的通配符匹配动态规划解法,以支持多模式。

步骤1:定义DP状态
对于单个模式 p,定义 dp[i][j] 表示字符串 s 的前 i 个字符和模式 p 的前 j 个字符是否匹配。

  • i 范围:0len(s)i=0 表示空字符串)
  • j 范围:0len(p)j=0 表示空模式)

步骤2:初始化边界条件

  • dp[0][0] = true:空字符串匹配空模式。
  • 对于 j ≥ 1,仅当 p 的前 j 个字符全是 * 时,dp[0][j] = true(因为 * 可匹配空序列)。
  • 对于 i ≥ 1dp[i][0] = false:空模式无法匹配非空字符串。

步骤3:状态转移方程
遍历 i1len(s)j1len(p)

  1. p[j-1] 是普通字符:需满足 s[i-1] == p[j-1]dp[i-1][j-1] == true
    • 即:dp[i][j] = dp[i-1][j-1] && (s[i-1] == p[j-1])
  2. p[j-1]?:它匹配任意单个字符,直接继承 dp[i-1][j-1]
    • 即:dp[i][j] = dp[i-1][j-1]
  3. p[j-1]*:可匹配空序列(忽略 *,即 dp[i][j-1])或匹配多个字符(保留 * 继续匹配,即 dp[i-1][j])。
    • 即:dp[i][j] = dp[i][j-1] || dp[i-1][j]

步骤4:多模式处理
patterns 中的每个模式 p,执行上述DP过程,若任意 p 满足 dp[len(s)][len(p)] == true,则返回 true;否则检查下一个模式。若所有模式均不匹配,返回 false

步骤5:优化

  • 当某个模式匹配成功时立即返回,避免不必要的计算。
  • 可提前检查模式是否包含普通字符(非通配符)且其数量超过 s 的长度,直接跳过。

举例说明
s = "abcd", p = "a*c?" 为例:

  • 初始化:dp[0][0] = truedp[0][1]p[0]='a')为 falsedp[0][2]p[1]='*')需看前一位:dp[0][1]false,但 dp[0][2] 需结合 * 的规则,实际因 * 可匹配空,需从头检查:正确初始化后 dp[0][2] = true(因为 a** 前有 a,但初始化时 i=0 仅当模式前j个全为*才真,此处需按规则重新计算)。
    具体计算时:
    • i=1,j=1s[0]='a' 匹配 p[0]='a',且 dp[0][0]=truedp[1][1]=true
    • i=1,j=2p[1]='*',可忽略(继承 dp[1][1]=true)或匹配多字符(但 i=1dp[0][2] 未计算,需逐行计算)。
      最终 dp[4][4]true,匹配成功。

通过以上步骤,可高效解决多模式通配符匹配问题。

通配符匹配(Wildcard Matching)的进阶版:支持多模式匹配的通配符匹配 题目描述 给定一个输入字符串 s 和一组模式 patterns ,每个模式可以包含普通字符、通配符 ? (匹配任意单个字符)和 * (匹配任意字符序列,包括空序列)。判断字符串 s 是否能被 patterns 中的任意一个模式完全匹配。注意:匹配必须是完整的,即整个字符串 s 需被某个模式完全覆盖。 示例 输入: s = "abcd" , patterns = ["a*c?", "b*d", "a?d"] 输出: true 解释:模式 "a*c?" 可以匹配 "abcd" ( a 匹配 a , * 匹配 bc , c? 匹配 cd )。 解题过程 此问题可转化为对每个模式单独判断是否匹配 s ,只要有一个模式匹配成功即返回 true 。核心是扩展经典的通配符匹配动态规划解法,以支持多模式。 步骤1:定义DP状态 对于单个模式 p ,定义 dp[i][j] 表示字符串 s 的前 i 个字符和模式 p 的前 j 个字符是否匹配。 i 范围: 0 到 len(s) ( i=0 表示空字符串) j 范围: 0 到 len(p) ( j=0 表示空模式) 步骤2:初始化边界条件 dp[0][0] = true :空字符串匹配空模式。 对于 j ≥ 1 ,仅当 p 的前 j 个字符全是 * 时, dp[0][j] = true (因为 * 可匹配空序列)。 对于 i ≥ 1 , dp[i][0] = false :空模式无法匹配非空字符串。 步骤3:状态转移方程 遍历 i 从 1 到 len(s) , j 从 1 到 len(p) : 若 p[j-1] 是普通字符:需满足 s[i-1] == p[j-1] 且 dp[i-1][j-1] == true 。 即: dp[i][j] = dp[i-1][j-1] && (s[i-1] == p[j-1]) 若 p[j-1] 是 ? :它匹配任意单个字符,直接继承 dp[i-1][j-1] 。 即: dp[i][j] = dp[i-1][j-1] 若 p[j-1] 是 * :可匹配空序列(忽略 * ,即 dp[i][j-1] )或匹配多个字符(保留 * 继续匹配,即 dp[i-1][j] )。 即: dp[i][j] = dp[i][j-1] || dp[i-1][j] 步骤4:多模式处理 对 patterns 中的每个模式 p ,执行上述DP过程,若任意 p 满足 dp[len(s)][len(p)] == true ,则返回 true ;否则检查下一个模式。若所有模式均不匹配,返回 false 。 步骤5:优化 当某个模式匹配成功时立即返回,避免不必要的计算。 可提前检查模式是否包含普通字符(非通配符)且其数量超过 s 的长度,直接跳过。 举例说明 以 s = "abcd" , p = "a*c?" 为例: 初始化: dp[0][0] = true , dp[0][1] ( p[0]='a' )为 false , dp[0][2] ( p[1]='*' )需看前一位: dp[0][1] 为 false ,但 dp[0][2] 需结合 * 的规则,实际因 * 可匹配空,需从头检查:正确初始化后 dp[0][2] = true (因为 a* 中 * 前有 a ,但初始化时 i=0 仅当模式前j个全为 * 才真,此处需按规则重新计算)。 具体计算时: i=1,j=1 : s[0]='a' 匹配 p[0]='a' ,且 dp[0][0]=true → dp[1][1]=true 。 i=1,j=2 : p[1]='*' ,可忽略(继承 dp[1][1]=true )或匹配多字符(但 i=1 时 dp[0][2] 未计算,需逐行计算)。 最终 dp[4][4] 为 true ,匹配成功。 通过以上步骤,可高效解决多模式通配符匹配问题。