2008-09-25 10 views
41

J'aurais besoin d'effectuer des différences entre les chaînes Java. Je voudrais être en mesure de reconstruire une chaîne à partir de la chaîne d'origine et les versions diff. Est-ce que quelqu'un a fait cela en Java? Quelle bibliothèque utilisez-vous?Comment faire pour effectuer des chaînes de caractères en Java?

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 
+0

également voir http://stackoverflow.com/questions/479654/java-library-for-free-text-diff – Stewart

Répondre

44

Cette bibliothèque semble faire l'affaire: google-diff-match-patch. Il peut créer une chaîne de patch à partir de différences et permettre de réappliquer le patch.

modifier: Une autre solution pourrait être de https://code.google.com/p/java-diff-utils/

+0

Ce sont différentes libs, FWIW – Kerinin

+4

Maven Le référentiel pour google-diff-match-patch est [there] (https://bitbucket.org/cowwoc/google-diff-match-patch/wiki/Home). – fracz

+4

La branche activement maintenue de java-diff-utils semble être https://github.com/bkromhout/java-diff-utils – koppor

19

Apache Commons a cordes diff

org.apache.commons.lang.StringUtils

StringUtils.difference("foobar", "foo"); 
+5

Il retourne le reste de la deuxième chaîne, à partir d'où il est différent du premier. Ce qui n'est pas assez efficace pour moi puisque je travaillerais avec de gros textes. Voir: StringUtils.difference ("ab", "abxyz") -> "xyz" StringUtils.différence ("ab", "xyzab") -> "xyzab"; –

+1

Aussi méfiez-vous ce Gotcha: 'StringUtils.difference ("abc", "") = ""' ' StringUtils.difference ("abc", "abc") = ""' – Alec

1

Utilisez les Levenshtein distance et extraire les journaux d'édition de la matrice de l'algorithme se forme. L'article de Wikipédia est lié à quelques implémentations, je suis sûr qu'il y a une implémentation de Java parmi.

Levenshtein est un cas particulier de l'algorithme Longest Common Subsequence, vous pouvez également jeter un coup d'oeil à cela.

4

Torsten dit que vous pouvez utiliser

org.apache.commons.lang.StringUtils;

System.err.println(StringUtils.getLevenshteinDistance("foobar", "bar")); 
+0

Merci, mais getLevenshteinDistance renvoie juste un entier. Ce n'est pas suffisant pour reconstruire les chaînes. –

+0

@hstoerr vous avez raison, je dois avoir raté cette partie de la question initiale. Il ya longtemps maintenant :) –

1

Si vous devez traiter des différences entre les grandes quantités de données et ont les différences efficacement compressées, vous pouvez essayer une implémentation Java de xdelta, ce qui met en œuvre la RFC 3284 (VCDIFF) pour les diffs binaires (devrait fonctionner avec des cordes aussi).

4

La bibliothèque java diff utills peut être utile.

+2

Le repo https://github.com/bkromhout/java-diff-utils/ est dérivé indirectement du référentiel GitHub original et est mieux maintenu. Peut-être que vous pouvez joindre vos forces là-bas? – koppor

-4
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; 

    } 
    } 
+1

Le code texte non testé tel que celui-ci n'a presque jamais de sens. Créez un projet sur une page d'hébergement de code FLOSS et fournissez le code + tests ici. –

Questions connexes