Мне нужно выполнить различия между строками Java. Я хотел бы иметь возможность перестроить строку, используя исходную версию строки и diff. Кто-нибудь делал это на Яве? Какую библиотеку вы используете?
String a1; // This can be a long text
String a2; // ej. above text with spelling corrections
String a3; // ej. above text with spelling corrections and an additional sentence
Diff diff = new Diff();
String differences_a1_a2 = Diff.getDifferences(a,changed_a);
String differences_a2_a3 = Diff.getDifferences(a,changed_a);
String[] diffs = new String[]{a,differences_a1_a2,differences_a2_a3};
String new_a3 = Diff.build(diffs);
a3.equals(new_a3); // this is true




Apache Commons имеет String diff
org.apache.commons.lang.StringUtils
StringUtils.difference("foobar", "foo");
Он возвращает остаток от второй строки, начиная с того места, где она отличается от первой. Для меня это недостаточно эффективно, так как я буду работать с большими текстами. См .: StringUtils.difference («ab», «abxyz») -> «xyz» StringUtils.difference («ab», «xyzab») -> «xyzab»;
Также остерегайтесь этой ошибки: StringUtils.difference("abc", "") = ""StringUtils.difference("abc", "abc") = ""
Используйте Расстояние Левенштейна и извлеките журналы редактирования из матрицы, которую создает алгоритм. В статье в Википедии есть ссылки на несколько реализаций, я уверен, что среди них есть реализация Java.
Левенштейн - это частный случай алгоритма Самая длинная общая подпоследовательность, вы также можете взглянуть на него.
Кажется, эта библиотека помогает: Google-diff-match-patch. Он может создать строку патча из различий и позволить повторно применить патч.
редактировать: Другим решением может быть https://code.google.com/p/java-diff-utils/
Это разные библиотеки, FWIW
Репозиторий Maven для google-diff-match-patch - там.
Активно поддерживаемый форк java-diff-utils выглядит как github.com/bkromhout/java-diff-utils
google-diff-match-patch на github: github.com/GerHobbelt/google-diff-match-patch
Поддерживаемая вилка, похоже, теперь github.com/java-diff-utils/java-diff-utils
Как говорит Торстен, вы можете использовать
org.apache.commons.lang.StringUtils;
System.err.println(StringUtils.getLevenshteinDistance("foobar", "bar"));
Спасибо, но getLevenshteinDistance просто возвращает целое число. Этого недостаточно, чтобы восстановить струны.
@hstoerr, вы правы, я, должно быть, пропустил эту часть в исходном вопросе. Давным-давно :)
Этот метод также устарел.
Если вам нужно иметь дело с различиями между большими объемами данных и эффективно сжать различия, вы можете попробовать Java-реализацию xdelta, которая, в свою очередь, реализует RFC 3284 (VCDIFF) для двоичных различий (также должна работать со строками).
Может пригодиться библиотека Различия в Java.
Репозиторий github.com/bkromhout/java-diff-utils был создан косвенно из исходного репозитория GitHub и лучше поддерживается. Может, там можно объединить силы?
public class Stringdiff {
public static void main(String args[]){
System.out.println(strcheck("sum","sumsum"));
}
public static String strcheck(String str1,String str2){
if (Math.abs((str1.length()-str2.length()))==-1){
return "Invalid";
}
int num=diffcheck1(str1, str2);
if (num==-1){
return "Empty";
}
if (str1.length()>str2.length()){
return str1.substring(num);
}
else{
return str2.substring(num);
}
}
public static int diffcheck1(String str1,String str2)
{
int i;
String str;
String strn;
if (str1.length()>str2.length()){
str=str1;
strn=str2;
}
else{
str=str2;
strn=str1;
}
for(i=0;i<str.length() && i<strn.length();i++){
if (str1.charAt(i)!=str2.charAt(i)){
return i;
}
}
if (i<str1.length()||i<str2.length()){
return i;
}
return -1;
}
}
Такой непроверенный текстовый код почти никогда не имеет смысла. Создайте проект на странице хостинга кода FLOSS и разместите там код + тесты.
Текст Apache Commons теперь имеет StringsComparator:
StringsComparator c = new StringsComparator(s1, s2);
c.getScript().visit(new CommandVisitor<Character>() {
@Override
public void visitKeepCommand(Character object) {
System.out.println("k: " + object);
}
@Override
public void visitInsertCommand(Character object) {
System.out.println("i: " + object);
}
@Override
public void visitDeleteCommand(Character object) {
System.out.println("d: " + object);
}
});
Также см. stackoverflow.com/questions/479654/…