【发布时间】:2019-07-03 21:57:48
【问题描述】:
我最近收到一个面试问题,我需要在不使用正则表达式匹配的情况下在 Java 中实现正则表达式匹配。
给定一个输入字符串 (s) 和一个模式 (p),实现正则 支持“.”、“+”、“*”和“?”的表达式匹配。
// (pattern, match) --> bool does it match
// operators:
// . --> any char
// + --> 1 or more of prev char
// * --> 0 or more of prev char
// ? --> 0 or 1 of prev char
// (abc+c, abcccc) --> True
// (abcd*, abc) --> True
// (abc?c, abc) --> True
// (abc.*, abcsdfsf) --> True
我想出了下面的代码,它只实现了“。”和 '*' 但无法弄清楚如何实现其他人:
public static boolean isMatch(String s, String p) {
if (p.length() == 0) {
return s.length() == 0;
}
if (p.length() > 1 && p.charAt(1) == '*') { // second char is '*'
if (isMatch(s, p.substring(2))) {
return true;
}
if (s.length() > 0 && (p.charAt(0) == '.' || s.charAt(0) == p.charAt(0))) {
return isMatch(s.substring(1), p);
}
return false;
} else { // second char is not '*'
if (s.length() > 0 && (p.charAt(0) == '.' || s.charAt(0) == p.charAt(0))) {
return isMatch(s.substring(1), p.substring(1));
}
return false;
}
}
还有什么是解决这个问题的最佳方法?
【问题讨论】:
-
经常用(a的变体)标记dfa的github.com/samrushing/irken-tdfa实现正则表达式
-
在长达一个小时的采访中,递归匹配器无疑是预期的解决方案(在讨论了这在生产系统中这将是多么糟糕的想法之后)。您可以通过检查
xetc|| 重写和匹配xx*和x?etc来使用现有代码轻松实现x+etc. -
如果您希望匹配大多数实现支持的“最左边最长”规则,那么回溯就会成为一个问题。例如,给定
"abcdefxwvutsrqx","ab.*x"是否应该匹配整个字符串?如果是这样,那么".*"意味着您必须始终扫描整个字符串才能找到最后一个'x'字符。 -
@JimMischel 如果它只返回一个布尔值,那么您无需担心哪个匹配。这使它更容易。虽然你仍然可以编写灾难性的正则表达式。
-
Relevant:动态规划方案,例如。 stackoverflow.com/questions/49572289/…
标签: java algorithm data-structures