web-dev-qa-db-ja.com

Javaの2つの文字列の違いを抽出する

こんにちは2つの文字列があります。

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

「Hey There\n」という文字列に存在しないものを取得したい。メソッドを見つけましたが、この場合は失敗します:

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 "";
    }
}

誰でも助けてもらえますか?

18

google-diff-match-patch

Diff MatchおよびPatchライブラリは、プレーンテキストの同期に必要な操作を実行する堅牢なアルゴリズムを提供します。

差分:

プレーンテキストの2つのブロックを比較し、違いのリストを効率的に返します。

一致:

検索文字列が与えられると、プレーンテキストのブロック内で最適なあいまい一致を見つけます。精度と位置の両方に重み付けされています。

パッチ:

パッチのリストをプレーンテキストに適用します。基になるテキストが一致しない場合でも、ベストエフォートを使用してパッチを適用します。

現在、Java、JavaScript、Dart、C++、C#、Objective C、Lua、Pythonで利用できます。言語に関係なく、各ライブラリは同じAPIと同じ機能を備えています。すべてのバージョンには、包括的なテストハーネスもあります。

行またはワードの差分 wikiページがあり、行ごとの差分の実行方法を説明しています。

25
Mike Samuel

Apache CommonsStringUtilsを使用できます。 StringUtils API です。

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

StringTokenizerを使用して解決策を見つけました。以下はコードスニペットです

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;
}
4
VJ THAKUR

文字列をリストに変換し、次のメソッドを使用して結果を取得します 2つの配列リストから共通の値を削除する方法

2
Aditya Rai

外部ライブラリを使用しない場合は、次のJavaスニペットを使用して、効率的に差異を計算できます。

/**
 * 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]};
            }
        }
    });
}

このアプローチは、動的プログラミングを使用しています。総当たり方式ですべての組み合わせを試行しますが、すでに計算された部分文字列を記憶しているため、O(n ^ 2)で実行されます。

例:

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"}
1
jjoller

私はいくつかの解決策を探していましたが、必要なものが見つかりませんでしたので、2つのバージョンのテキストを比較するためのユーティリティクラスを作成しました-新しいものと古いもの-タグ間の変更を含む結果テキストを取得する-[追加]と[削除]このタグの代わりに選択した蛍光ペンに簡単に置き換えることができます。たとえば、htmlタグです。 string-version-comparison

コメントをいただければ幸いです。

*削除されたフレーズと同じフレーズを見つける可能性が高いため、長いテキストではうまく機能しない可能性があります。

0
ahanook

Apache CommonsのStringUtilsを使用する必要があります

0
gurbieta