這是產生以這樣的方式使得它們被長度和第一次出現有序增量的全部重複序列的算法。它基於一個簡單的想法:在一個句子中兩次找到一個單詞,相同的起始字母必須出現兩次。有一些解釋(算法保持不變)的Java代碼,它將輸出交織的重複,例如, BANANA => A,N,AN,NA,ANA(1,3),如果與前一個的距離小於字符串長度,則可以消除索引,以便在此算法中進行更正(下面的代碼是樣本運行,這應該更好地解釋它):
public List<String> getRepetitions(String string) {
List<String> repetitions = new ArrayList<String>();
Map<String, List<Integer>> rep = new HashMap<String, List<Integer>>(), repOld;
// init rep, add start position of all single character length strings
for (int i = 0; i < string.length(); i++) {
String s = string.substring(i, i + 1); // startIndex inclusive, endIndex exclusive
if (rep.containsKey(s)) {
rep.get(s).add(new Integer(i));
} else {
List<Integer> l = new ArrayList<Integer>();
l.add(new Integer(i));
rep.put(l);
}
}
// eliminate those with no repetitions and add the others to the solution
for (Map.Entry<String, Integer> e : rep.entrySet()) {
if (e.getValue().size() < 2) {
rep.remove(e.getKey());
} else {
repetitions.add(e.getKey());
}
}
for (int len = 1; rep.size() > 0; len++) {
repOld = rep;
rep = new HashMap<String, List<Integer>>();
for (Map.EntrySet<String, List<Integer>> e : repOld.entrySet()) {
for (Integer i : e.getValue()) { // for all start indices
if (i.intValue() + len + 1 >= string.length())
break;
String s = e.getKey() + string.charAt(i.intValue() + len + 1);
if (rep.containsKey(s)) {
rep.get(s).add(i);
} else {
List<Integer> l = new ArrayList<Integer>();
l.add(i);
rep.put(l);
}
}
}
// eliminate repetitions and add to solution
for (Map.Entry<String, Integer> e : rep.entrySet()) {
if (e.getValue().size() < 2) {
rep.remove(e.getKey());
} else {
repetitions.add(e.getKey());
}
}
}
return repetitions; // ordered by length, so last = longest
}
樣品運行香蕉:
- 單個字母添加到
rep
=>乙 - > [0],A - > [1,3,5] ,N - > [2,4]
- 消除少於2次出現的那些(B),將其他添加到溶液(A,N)
- add下列信剩餘occurances(創建新
rep
):AN - > [1,3],NA - > [2,4]
- 消除( - ),並添加(AN,NA)
- 重複步驟3和4。:ANA - > [1,3]
- 在週期
rep
將成爲空的,並且該算法結束
你的問題是要找到最長的重複子? – 1010
你需要做這樣的代碼可以和猜測密碼的「暴力」程序相媲美,並且它將非常緩慢地運行所有可能的子字符串並檢查所有其他子字符串。 – maksymiuk
與此格式完全相同還是在重複字符串之前/之後有/未使用過的文本片段? – maraca