- qt - 在 QNetworkAccessManager 中,何时从解析 DNS 的 IP 列表中选择 IP?
- java - OKHTTP——发布用户输入数据,检索 JSON 响应以确定成功
- java - 将 curl 请求转换为 URLConnection
- android - 使用主机名对本地机器的 Http 请求在 android 设备中不起作用
我试图理解一种著名的正则表达式匹配 DP 算法。以防万一,人们不知道这是描述和算法。
'.' Matches any single character.
'*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
The function prototype should be:
bool isMatch(const char *s, const char *p)
Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true
static boolean isMatch(String s, String p) {
boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
dp[0][0] = true;
for (int i = 1; i < dp[0].length; i++) {
if (p.charAt(i - 1) == '*') {
dp[0][i] = dp[0][i - 2];
}
}
for (int i = 1; i < dp.length; i++) {
for (int j = 1; j < dp[0].length; j++) {
char schar = s.charAt(i - 1);
char pchar = p.charAt(j - 1);
if (schar == pchar || pchar == '.') {
dp[i][j] = dp[i - 1][j - 1];
} else if (pchar == '*') {
if (schar != p.charAt(j - 2) && p.charAt(j - 2) != '.') {
// - a b *
// - t f f f
// a f t f t // b != a and b != '.' thus treat b* as 0 match
dp[i][j] = dp[i][j - 2];
} else {
// - a b *
// - t f f f
// a f t f t
// b f f t t // dp[i][j - 2] 0 match or dp[i][j - 1] 1 math or dp[i - 1][j] 2+ match (not sure why)
dp[i][j] = dp[i][j - 2] || dp[i][j - 1] || dp[i - 1][j];
}
}
}
}
return dp[s.length()][p.length()];
}
大部分我都听懂了,但是这部分我没听懂
dp[i][j] = dp[i][j - 2] || dp[i][j - 1] || dp[i - 1][j];
dp[i - 1][j]
人们说这将涵盖 2+ 场比赛,但不理解这部分。有人可以解释为什么我需要检查 dp[i - 1][j]
吗?
最佳答案
我将使用更非正式的符号,请耐心等待。大写字母将表示字符串(在模式中可能包含特殊字符)和小写字母“.”而“*”将代表他们自己。
假设我们正在将 Ax 与 Bx 进行匹配,这是一些以 A 开头的字符串(它本身就是一个字符串,如 xyzz)以 'x' 结尾,具有以 B 开头的模式(它本身就是一个模式,因为例如,x.*) 以“x”结尾。结果与将 A 匹配到 B 的结果相同(因为我们别无选择,只能将 x 匹配到 x)。
我们可以这样写:
isMatch(Ax, Bx) = isMatch(A, B)
同样,将 Ax 与 By 匹配是不可能的。
isMatch(Ax, Bx) = false
很简单。所以这将对应于两个嵌套循环中的第一个 if 语句。
现在让我们以星号为例。将 Ax 匹配到 By* 只能通过忽略 y*(y 取零)来完成,即通过将 Ax 匹配到 B。
isMatch(Ax, By*) = isMatch(Ax, B)
但是,如果 y 被点或 x 代替,则有选择。我们将以 Ax 和 Bx* 为例。这两个选项是将 Ax 匹配到 B(意味着取零个 x)或将 A 匹配到 Bx*(意味着取一个 x,但我们仍然可以取更多,这样模式就不会改变):
isMatch(Ax, Bx*) = isMatch(Ax, B) || isMatch(A, Bx*)
在您的代码中,最后一个将转换为:
dp[i][j] = dp[i][j - 2] || dp[i - 1][j]
现在我想知道你的问题是否真的是关于 dp[i][j - 1]
的,因为那会让我感到困惑。
我可能是错的,但那个似乎是不必要的。
意思是去掉星号,即变“零个或多个”到“恰好一个”,这已经被其他两个案例所涵盖,先是第二个,然后是第一个。
关于正则表达式匹配 dp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44865853/
我正在用 yacc/bison 编写一个简单的计算器。 表达式的语法看起来有点像这样: expr : NUM | expr '+' expr { $$ = $1 + $3; } | expr '-'
我开始学习 lambda 表达式,并在以下情况下遇到了以下语句: interface MyNumber { double getValue(); } MyNumber number; nu
这两个 Linq 查询有什么区别: var result = ResultLists().Where( c=> c.code == "abc").FirstOrDefault(); // vs. va
如果我们查看 draft C++ standard 5.1.2 Lambda 表达式 段 2 说(强调我的 future ): The evaluation of a lambda-expressio
我使用的是 Mule 4.2.2 运行时、studio 7.5.1 和 Oracle JDK 1.8.0_251。 我在 java 代码中使用 Lambda 表达式,该表达式由 java Invoke
我是 XPath 的新手。我有网页的html源 http://london.craigslist.co.uk/com/1233708939.html 现在我想从上面的页面中提取以下数据 完整日期 电子
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我将如何编写一个 Cron 表达式以在每天上午 8 点和下午 3:30 触发?我了解如何创建每天触发一次的表达式,而不是在多个设定时间触发。提前致谢 最佳答案 你应该只使用两行。 0 8 * * *
这个问题已经有答案了: What do 3 dots next to a parameter type mean in Java? (9 个回答) varargs and the '...' argu
我是 python 新手,在阅读 BeautifulSoup 教程时,我不明白这个表达式“[x for x in titles if x.findChildren()][:-1]”我不明白?你能解释一
(?:) 这是一个有效的 ruby 正则表达式,谁能告诉我它是什么意思? 谢谢 最佳答案 正如其他人所说,它被用作正则表达式的非捕获语法,但是,它也是正则表达式之外的有效 ruby 语法。 在
这个问题在这里已经有了答案: Why does ++[[]][+[]]+[+[]] return the string "10"? (10 个答案) 关闭 8 年前。 谁能帮我处理这个 JavaSc
这个问题在这里已经有了答案: What is the "-->" operator in C++? (29 个答案) Java: Prefix/postfix of increment/decrem
这个问题在这里已经有了答案: List comprehension vs. lambda + filter (16 个答案) 关闭 10 个月前。 我不确定我是否需要 lambda 或其他东西。但是,
C 中的 assert() 函数工作原理对我来说就像一片黑暗的森林。根据这里的答案https://stackoverflow.com/a/1571360 ,您可以使用以下构造将自定义消息输出到您的断言
在this页,John Barnes 写道: If the conditional expression is the argument of a type conversion then effec
我必须创建一个调度程序,它必须每周从第一天上午 9 点到第二天晚上 11 点 59 分运行 2 天(星期四和星期五)。为此,我需要提供一个 cron 表达式。 0-0 0-0 9-23 ? * THU
我正在尝试编写一个 Linq 表达式来检查派生类中的属性,但该列表由来自基类的成员组成。下面的示例代码。以“var list”开头的 Process 方法的第二行无法编译,但我不确定应该使用什么语法来
此 sed 表达式将输入字符串转换为两行输出字符串。两条输出行中的每一行都由输入的子串组成。第一行需要转换成大写: s:random_stuff\(choice1\|choice2\){\([^}]*
我正在使用 Quartz.Net 在我的应用程序中安排我的工作。我只是想知道是否可以为以下场景构建 CRON 表达式: Every second between 2:15AM and 5:20AM 最
我是一名优秀的程序员,十分优秀!