动态规划(字符串通配符匹配)

本文深入浅出地讲解了动态规划在带有通配符的字符串匹配中的应用,通过实例解析算法原理,帮助读者理解并掌握这一高效算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

### 字符串通配符匹配算法实现 字符串通配符匹配是一种用于判断两个字符串是否匹配的常见技术,通常涉及两种特殊的通配符 `*` 和 `?`。以下是基于动态规划方法的一种高效实现方式。 #### 动态规划的核心思路 通过构建二维布尔数组 `dp[i][j]` 来表示输入字符串 `s` 的前 `i` 个字符与模式字符串 `p` 的前 `j` 个字符是否可以匹配。状态转移方程如下: - 如果当前字符相等或者模式中的字符为 `?`,则有: \( dp[i][j] = dp[i-1][j-1] \)[^5] - 如果模式中的字符为 `*`,它可以代表零个或多个字符,则有两种情况: - 当作空字符序列时:\( dp[i][j] = dp[i][j-1] \) - 当作至少一个字符时:\( dp[i][j] = dp[i-1][j] \) 最终的状态转移公式为: \[ dp[i][j] = dp[i][j-1] || dp[i-1][j], \text{当 } p[j-1] == '*' \] \[ dp[i][j] = dp[i-1][j-1], \text{当 } p[j-1] == '?' \text{ 或者 } s[i-1] == p[j-1] \] 初始条件设置为: - \( dp[0][0] = true \),即空字符串和空模式匹配。 - 对于模式以若干个 `*` 开头的情况,允许其与空字符串匹配。 下面是完整的 C++ 实现代码: ```cpp #include <iostream> #include <vector> using namespace std; bool isMatch(string s, string p) { int m = s.size(); int n = p.size(); vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false)); dp[0][0] = true; // 初始化边界条件 for(int j = 1; j <= n && p[j-1] == '*'; ++j){ dp[0][j] = true; } // 填充 DP 表格 for(int i = 1; i <= m; ++i){ for(int j = 1; j <= n; ++j){ if(p[j-1] == '?'){ dp[i][j] = dp[i-1][j-1]; } else if(p[j-1] == '*'){ dp[i][j] = dp[i][j-1] || dp[i-1][j]; } else{ dp[i][j] = (s[i-1] == p[j-1]) && dp[i-1][j-1]; } } } return dp[m][n]; } int main(){ string s = "aa"; string p = "*"; cout << boolalpha << isMatch(s, p); // 输出 true/false } ``` 此代码实现了动态规划解法来处理通配符匹配问题。时间复杂度为 O(m*n),空间复杂度同样为 O(m*n),其中 `m` 是输入字符串长度,`n` 是模式字符串长度。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值