利用KMP算法。算法的狀態決定了「乾草堆的最長後綴仍然是針的前綴」。所以,只要把你的繩子作爲針和沒有第一個字符的繩子當乾草堆。在O(N)
時間和O(N)
空間運行。
與一些示例的實現:
public static int[] create(String needle) {
int[] backFunc = new int[needle.length() + 1];
backFunc[0] = backFunc[1] = 0;
for (int i = 1; i < needle.length(); ++i) {
int testing = i - 1;
while (backFunc[testing] != testing) {
if (needle.charAt(backFunc[testing]) == needle.charAt(i-1)) {
backFunc[i] = backFunc[testing] + 1;
break;
} else {
testing = backFunc[testing];
}
}
}
return backFunc;
}
public static int find(String needle, String haystack) {
// some unused character to ensure that we always return back and never reach the end of the
// needle
needle = needle + "$";
int[] backFunc = create(needle);
System.out.println(Arrays.toString(backFunc));
int curpos = 0;
for (int i = 0; i < haystack.length(); ++i) {
while (curpos != backFunc[curpos]) {
if (haystack.charAt(i) == needle.charAt(curpos)) {
++curpos;
break;
} else {
curpos = backFunc[curpos];
}
}
if (curpos == 0 && needle.charAt(0) == haystack.charAt(i)) {
++curpos;
}
System.out.println(curpos);
}
return curpos;
}
public static void main(String[] args) {
String[] tests = {"abababa", "tsttst", "acblahac", "aaaaa"};
for (String test : tests) {
System.out.println("Length is : " + find(test, test.substring(1)));
}
}
看那克努特 - Morris-普拉特算法。作爲該算法的一部分,您可以使用空間O(n)在時間O(n)中找到此屬性的最長邊界。 – templatetypedef
瑣碎的解決方案是返回整個字符串:-)。防爆。 '([ABABABA)]'。我猜你想要除了上述之外的最大可能值? – Kevin
你能否展示一個例子,其中的前綴與其背面不一樣? - 不清楚前綴和後綴是否都從外部開始(aabxnbaa中的'aab'),還是從左側開始(aabxnaab中的「aab」或整個字符串,如Kevin提到)。 – Dukeling