前一段时间的 LCS问题
LCS 问题及其扩展,找到多个字符串的所有公共子串
用后缀树的方法 ,看了编程珠玑后觉得后缀树组更简洁高效 ,故重新实现下
找出单个字符串最长的重复子串以及最长的出现m次的子串。
import java.util.ArrayList;
import java.util.Collections;
/**
* User: yiminghe
* Date: 2009-3-2
* Time: 23:36:32
*/
public class LCS {
//得到单词的后缀树组并按照字母顺序排序
private static ArrayList<String> getSuffixArray(String s) {
ArrayList<String> al = new ArrayList<String>();
int l = s.length();
for (int i = 0; i < l; i++) {
al.add(s.substring(i));
}
Collections.sort(al);
return al;
}
/**
* @param s 字符串
* @return 最长的重复m次字符串
*/
public static String getLongestCommonSubstring(String s, int m) {
String longStr = "";
String[] suffixes = getSuffixArray(s).toArray(new String[0]);
for (int i = 0; i < suffixes.length - (m - 1); i++) {
int tl = getCommonLength(suffixes, i, i + m - 1);
if (tl > longStr.length())
longStr = suffixes[i].substring(0, tl);
}
return longStr;
}
//得到n个单词相同的位数
private static int getCommonLength(String[] s, int start, int end) {
int c = 0;
while (true) {
for (int i = start; i <= end; i++)
if (s[i].length() <= c) return c;
for (int i = start; i < end; i++)
if (s[i].charAt(c) != s[i + 1].charAt(c)) return c;
++c;
}
}
public static void main(String[] args) {
String test = "banana";
System.out.println(getLongestCommonSubstring(test,3));
}
}