web-dev-qa-db-fra.com

Extraire la différence entre deux chaînes en Java

Salut j'ai deux cordes:

    String hear = "Hi My name is Deepak"
            + "\n"
            + "How are you ?"
            + "\n"
            + "\n"
            + "How is everyone";
    String dear = "Hi My name is Deepak"
            + "\n"
            + "How are you ?"
            + "\n"
            + "Hey there \n"
            + "How is everyone";

Je veux obtenir ce qui n'est pas présent dans la chaîne de lecture qui est "Hey There\n". J'ai trouvé une méthode, mais elle échoue pour ce cas:

static String strDiffChop(String s1, String s2) {
    if (s1.length() > s2.length()) {
        return s1.substring(s2.length() - 1);
    } else if (s2.length() > s1.length()) {
        return s2.substring(s1.length() - 1);
    } else {
        return "";
    }
}

Quelqu'un peut-il aider?

16
N Deepak Prasath

google-diff-match-patch

Les bibliothèques de correspondance diff et de correctifs offrent des algorithmes robustes pour effectuer les opérations requises pour la synchronisation de texte brut.

Diff:

Comparez deux blocs de texte brut et renvoyez efficacement une liste de différences.

Rencontre:

À partir d’une chaîne de recherche, trouvez la meilleure correspondance floue dans un bloc de texte brut. Pondéré pour la précision et l'emplacement.

Pièce:

Appliquez une liste de correctifs sur du texte brut. Faites de votre mieux pour appliquer le correctif même lorsque le texte sous-jacent ne correspond pas.

Actuellement disponible en Java, JavaScript, Dart, C++, C #, Objective C, Lua et Python. Quelle que soit la langue, chaque bibliothèque dispose de la même API et des mêmes fonctionnalités. Toutes les versions ont également des faisceaux de test complets.

Il existe une page wiki diffs page wiki qui décrit comment faire des différences ligne par ligne.

23
Mike Samuel

On peut utiliser la StringUtils de Apache Commons . Voici l’API StringUtils .

public static String difference(String str1, String str2) {
    if (str1 == null) {
        return str2;
    }
    if (str2 == null) {
        return str1;
    }
    int at = indexOfDifference(str1, str2);
    if (at == -1) {
        return EMPTY;
    }
 return str2.substring(at);
}
public static int indexOfDifference(String str1, String str2) {
    if (str1 == str2) {
        return -1;
    }
    if (str1 == null || str2 == null) {
        return 0;
    }
    int i;
    for (i = 0; i < str1.length() && i < str2.length(); ++i) {
        if (str1.charAt(i) != str2.charAt(i)) {
            break;
        }
    }
    if (i < str2.length() || i < str1.length()) {
        return i;
    }
    return -1;
}
7
Fly

J'ai utilisé le StringTokenizer pour trouver la solution. Ci-dessous l'extrait de code

public static List<String> findNotMatching(String sourceStr, String anotherStr){
    StringTokenizer at = new StringTokenizer(sourceStr, " ");
    StringTokenizer bt = null;
    int i = 0, token_count = 0;
    String token = null;
    boolean flag = false;
    List<String> missingWords = new ArrayList<String>();
    while (at.hasMoreTokens()) {
        token = at.nextToken();
        bt = new StringTokenizer(anotherStr, " ");
        token_count = bt.countTokens();
        while (i < token_count) {
            String s = bt.nextToken();
            if (token.equals(s)) {
                flag = true;
                break;
            } else {
                flag = false;
            }
            i++;
        }
        i = 0;
        if (flag == false)
            missingWords.add(token);
    }
    return missingWords;
}
3
VJ THAKUR

convertit la chaîne en listes, puis utilise la méthode suivante pour obtenir le résultat Comment supprimer les valeurs communes de deux listes de tableaux

2
Aditya Rai

Je recherchais une solution, mais je ne trouvais pas celle dont j'avais besoin. J'ai donc créé une classe utilitaire permettant de comparer deux versions de texte - nouvelle et ancienne - et d'obtenir le texte du résultat avec les modifications entre balises - [ajouté] et [supprimé]. Il pourrait être facilement remplacé par le surligneur de votre choix au lieu de ces balises, par exemple: une balise html. comparaison de version de chaîne

Tous les commentaires seront appréciés. 

* cela risque de ne pas bien fonctionner avec un texte long en raison de la probabilité plus élevée de trouver les mêmes phrases que celles supprimées.

0
ahanook

Vous devriez utiliser StringUtils d'Apache Commons

0
gurbieta

Si vous préférez ne pas utiliser de bibliothèque externe, vous pouvez utiliser le fragment de code Java suivant pour calculer efficacement la différence:

/**
 * Returns an array of size 2. The entries contain a minimal set of characters
 * that have to be removed from the corresponding input strings in order to
 * make the strings equal.
 */
public String[] difference(String a, String b) {
    return diffHelper(a, b, new HashMap<>());
}

private String[] diffHelper(String a, String b, Map<Long, String[]> lookup) {
    return lookup.computeIfAbsent(((long) a.length()) << 32 | b.length(), k -> {
        if (a.isEmpty() || b.isEmpty()) {
            return new String[]{a, b};
        } else if (a.charAt(0) == b.charAt(0)) {
            return diffHelper(a.substring(1), b.substring(1), lookup);
        } else {
            String[] aa = diffHelper(a.substring(1), b, lookup);
            String[] bb = diffHelper(a, b.substring(1), lookup);
            if (aa[0].length() + aa[1].length() < bb[0].length() + bb[1].length()) {
                return new String[]{a.charAt(0) + aa[0], aa[1]};
            } else {
                return new String[]{bb[0], b.charAt(0) + bb[1]};
            }
        }
    });
}

Cette approche utilise la programmation dynamique. Il essaie toutes les combinaisons de manière brutale, mais se souvient des sous-chaînes déjà calculées et s'exécute donc en O (n ^ 2).

Exemples:

String hear = "Hi My name is Deepak"
        + "\n"
        + "How are you ?"
        + "\n"
        + "\n"
        + "How is everyone";
String dear = "Hi My name is Deepak"
        + "\n"
        + "How are you ?"
        + "\n"
        + "Hey there \n"
        + "How is everyone";
difference(hear, dear); // returns {"","Hey there "}

difference("Honda", "Hyundai"); // returns {"o","yui"}

difference("Toyota", "Coyote"); // returns {"Ta","Ce"}
0
jjoller