首先查找最长的公共子字符串将比仅检查是否存在至少给定大小的匹配项要慢。您可以在找到匹配项后立即停止,即使可能有更长的匹配项。
我将构建一个哈希集(如果要求更复杂,则为哈希映射),它代表所有长度为 N 的子字符串(不实际创建这些子字符串),并使用它来扫描长度为 N 的字符串以查找可能匹配。
您可以在 O(M) 时间内完成此操作,其中 M 是最长字符串的长度。
你可以像这样创建一个子字符串类。
class Substring {
final String s;
final int offset, length, hashCode;
Substring(String s, int offset, int length) {
this.s = s;
this.offset = offset;
this.length = length;
this.hashCode = hashCode(s, offset, length); // define to taste
}
public int hashCode() { return hashCode; }
public boolean equals(Object o) {
if (!(o instanceof Substring)) return false;
Substring ss = (Substring) s;
if (hashCode != ss.hashCode || length != ss.length) return false;
for (int i = 0; i < length; i++)
if (s.charAt(i) != ss.s.charAt(i))
return false;
return true;
}
}
要构建 HashSet,您可以在 O(n) 中执行以下操作,其中 n 是 s1.length()
Set<Substring> substrings = new HashSet<>();
for (int i = 0; i < s1.length() - n; i++) {
Substring ss = new Substring(s1, i, n);
substrings.add(ss);
}
要搜索匹配项,您可以在O(n) 中执行以下操作,其中 n 是 s2.length()
for (int i = 0; i < s2.length() - n; i++) {
Substring ss = new Substring(s2, i, n);
if (substrings.contains(ss))
return true; // found a match.
}