实现了一个正则表达式匹配算法,支持正则表达式中的基本字符和特殊字符 .
和 *
。具体来说:
.
:匹配任意单个字符。*
:匹配零个或多个前面的字符。
-
类
RegexMatcher
:- 负责正则表达式匹配的核心功能。
- 主要包含两个函数:
charMatch
和isMatch
。
-
函数
charMatch
:- 用于检查两个字符是否匹配。
- 支持点号
.
的匹配,即任何字符与.
都匹配。
-
函数
isMatch
:- 使用动态规划来判断给定的字符串
s
是否与模式p
匹配。 - 创建一个二维动态规划表
dp
,其中dp[i][j]
表示s
的前i
个字符和p
的前j
个字符是否匹配。
- 使用动态规划来判断给定的字符串
动态规划表dp
的填充逻辑:
-
初始化:
dp[0][0]
表示空字符串和空模式匹配,设置为true
。- 处理模式以星号开头的情况,即
p[j-1] == '*'
时,dp[0][j] = dp[0][j-2]
。
-
填充
dp
表:- 遍历字符串
s
和模式p
的所有字符。 - 如果
p[j-1] == '*'
,则有两种情况:- 星号匹配零次:
dp[i][j] = dp[i][j-2]
。 - 星号匹配一次或多次:如果
charMatch(s[i-1], p[j-2])
为真,则dp[i][j] = dp[i][j] || dp[i-1][j]
。
- 星号匹配零次:
- 如果当前字符匹配(通过
charMatch
函数判断),则dp[i][j] = dp[i-1][j-1]
。
- 遍历字符串
-
最终结果:
- 返回
dp[m][n]
,即字符串s
的前m
个字符和模式p
的前n
个字符是否匹配。
- 返回
#include <iostream> // 包含输入输出流库
#include <string> // 包含字符串库
#include <vector> // 包含向量库,用于动态规划
class RegexMatcher {
private:
// 辅助函数,用于检查两个字符是否匹配(考虑点号的情况)
bool charMatch(char s, char p) {
return p == '.' || s == p; // 如果模式字符是点号或者两个字符相等,则匹配
}
public:
// 主要的匹配函数
bool isMatch(const std::string& s, const std::string& p) {
int m = s.length(); // 获取字符串长度
int n = p.length(); // 获取模式长度
// 创建动态规划表,dp[i][j]表示s的前i个字符和p的前j个字符是否匹配
std::vector<std::vector<bool>> dp(m + 1, std::vector<bool>(n + 1, false));
// 空字符串匹配空模式
dp[0][0] = true;
// 处理模式以星号开始的情况
for (int j = 1; j <= n; j++) {
if (p[j-1] == '*') {
dp[0][j] = dp[0][j-2];
}
}
// 填充动态规划表
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (p[j-1] == '*') {
// 星号可以匹配零次或多次
dp[i][j] = dp[i][j-2]; // 匹配零次
if (charMatch(s[i-1], p[j-2])) {
dp[i][j] = dp[i][j] || dp[i-1][j]; // 匹配一次或多次
}
} else if (charMatch(s[i-1], p[j-1])) {
// 当前字符匹配
dp[i][j] = dp[i-1][j-1];
}
}
}
return dp[m][n]; // 返回最终的匹配结果
}
};
int main() {
RegexMatcher matcher; // 创建RegexMatcher对象
// 测试用例
std::cout << "aa vs a: " << (matcher.isMatch("aa", "a") ? "true" : "false") << std::endl;
std::cout << "aa vs a*: " << (matcher.isMatch("aa", "a*") ? "true" : "false") << std::endl;
std::cout << "ab vs .*: " << (matcher.isMatch("ab", ".*") ? "true" : "false") << std::endl;
std::cout << "aab vs c*a*b: " << (matcher.isMatch("aab", "c*a*b") ? "true" : "false") << std::endl;
std::cout << "mississippi vs mis*is*p*.: " << (matcher.isMatch("mississippi", "mis*is*p*.") ? "true" : "false") << std::endl;
return 0; // 程序正常结束
}