📌  相关文章
📜  教资会网络 | UGC NET CS 2016 年 7 月 – II |问题 3(1)

📅  最后修改于: 2023-12-03 14:54:49.669000             🧑  作者: Mango

UGC NET CS 2016 年 7 月 - II | 问题 3

这个问题主要涉及到匹配问题,需要写一个程序来检查输入的字符串是否符合某种模式。

问题描述

给定两个字符串 $s$ 和 $p$ ,其中 $p$ 可以包括小写字母 a-z 和通配符 ?* 。请编写一个函数来判断字符串 $s$ 是否符合模式 $p$。

其中,? 可以匹配任意一个字符,而 * 可以匹配任意多个字符(包括空字符)。

例如:

isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false
解题思路

这个问题可以用动态规划的思路来解决。我们定义一个二维数组 f,其中 $f_{i,j}$ 表示字符串 $s$ 的前 $i$ 个字符是否可以被字符串 $p$ 的前 $j$ 个字符所匹配。

  • 当 $p_j$ 是小写字母时,如果 $s_i=p_j$,则 $f_{i,j} = f_{i-1,j-1}$,否则 $f_{i,j}=false$;
  • 当 $p_j$ 是 ? 时,可以匹配任意一个字符,因此 $f_{i,j}=f_{i-1,j-1}$;
  • 当 $p_j$ 是 * 时,可以匹配任意多个字符,因此可以选取或者不选取该字符。如果不选取,则 $f_{i,j}=f_{i,j-1}$;如果选取,则 $f_{i,j}=f_{i-1,j}$。

最终,答案即为 $f_{len(s),len(p)}$,其中 $len(s)$ 表示字符串 $s$ 的长度,$len(p)$ 表示字符串 $p$ 的长度。

程序代码
def isMatch(s: str, p: str) -> bool:

    m, n = len(s), len(p)

    # 初始化二维数组
    f = [[False] * (n + 1) for _ in range(m + 1)]

    # 边界条件
    f[0][0] = True
    for j in range(1, n + 1):
        if p[j - 1] == '*':
            f[0][j] = True
        else:
            break

    # 状态转移
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if p[j - 1] == s[i - 1] or p[j - 1] == '?':
                f[i][j] = f[i - 1][j - 1]
            elif p[j - 1] == '*':
                f[i][j] = f[i][j - 1] or f[i - 1][j]

    return f[m][n]

上面的代码中,输入参数 sp 分别表示给定的两个字符串;返回值为布尔类型,表示字符串 $s$ 是否符合模式 $p$。具体的实现细节见注释。