Реализация Java для самой длинной общей подстроки из n строк
Мне нужно найти самую длинную общую подстроку из n строк и использовать результат в моем проекте.
Есть ли какая-либо существующая реализация / библиотека в Java, которая уже делает это?
Спасибо за ваши ответы заранее.
5 ответов
А как насчет параллельных деревьев?
Это небольшая (~100 КБ) библиотека, доступная в Maven Central. Алгоритм использует комбинацию Radix и Suffix Trees. Который, как известно, имеет линейную сложность времени ( Википедия).
public static String getLongestCommonSubstring(Collection<String> strings) {
LCSubstringSolver solver = new LCSubstringSolver(new DefaultCharSequenceNodeFactory());
for (String s: strings) {
solver.add(s);
}
return solver.getLongestCommonSubstring().toString();
}
Мы можем использовать приведенный ниже код для определения самой длинной общей подстроки из n строк
public static String identifyCommonSubStrOfNStr(String [] strArr){
String commonStr="";
String smallStr ="";
//identify smallest String
for (String s :strArr) {
if(smallStr.length()< s.length()){
smallStr=s;
}
}
String tempCom="";
char [] smallStrChars=smallStr.toCharArray();
for (char c: smallStrChars){
tempCom+= c;
for (String s :strArr){
if(!s.contains(tempCom)){
tempCom=c;
for (String s :strAarr){
if(!s.contains(tempCom)){
tempCom="";
break;
}
}
break;
}
}
if(tempCom!="" && tempCom.length()>commonStr.length()){
commonStr=tempCom;
}
}
return commonStr;
}
Эта страница в значительной степени дает именно то, что вы хотите на нескольких языках.
public static int longestSubstr(String first, String second) {
if (first == null || second == null || first.length() == 0 || second.length() == 0) {
return 0;
}
int maxLen = 0;
int fl = first.length();
int sl = second.length();
int[][] table = new int[fl][sl];
for (int i = 0; i < fl; i++) {
for (int j = 0; j < sl; j++) {
if (first.charAt(i) == second.charAt(j)) {
if (i == 0 || j == 0) {
table[i][j] = 1;
}
else {
table[i][j] = table[i - 1][j - 1] + 1;
}
if (table[i][j] > maxLen) {
maxLen = table[i][j];
}
}
}
}
return maxLen;
}
Ну, вы можете попытаться расширить версию Википедии ( http://en.wikipedia.org/wiki/Longest_common_substring_problem) для n строк, поместив ее в цикл, который выполняет итерацию по всем вашим строкам.
public String findLongestCommonSubstring(String source, String dest) {
int table[][] = new int[source.length() + 1][dest.length() + 1];
for (int col = 0; col < table[0].length; col++) {
table[0][col] = 0;
}
for (int row = 0; row < table.length; row++) {
table[row][0] = 0;
}
int max = 0;
int index = 0;
for (int row = 1; row < table.length; row++) {
char sourceChar = source.charAt(row - 1);
for (int col = 1; col < table[row].length; col++) {
char destChar = dest.charAt(col - 1);
if (sourceChar == destChar) {
table[row][col] = table[row - 1][col - 1] + 1;
if (table[row][col] > max) {
max = table[row][col];
index = row;
}
} else {
table[row][col] = 0;
}
}
}
return source.substring(index - max, index);
}