3

例えば:

S1: "some filename contains few words.txt"
S2: "some filename contains few words - draft.txt"
S3: "some filename contains few words - another draft.txt"
S4: "some filename not contains few words.txt"

最初の文字列と他の文字列を一致させるためにS2またはS3を取得できることに注意してください。

編集済み:「マスター」文字列があり、一致するものを見つける必要があります。

最初のラウンドでタイプミスを見つけたとしましょう。

今、私は単語全体だけを一致させる必要があります。

7語中5語、または10語中7語が一致するかどうかを判断できるようにしたいのですが、「XoutofY」の正確な数はそれほど重要ではありません。

重要なのは、違いがX語であり、文のどこにあるかを判断する方法です。

ありがとう

4

2 に答える 2

7

これは正規表現の問題ではありません。

言語は指定しませんが、Java を使用している場合getLevenshteinDistanceは StringUtils のメソッドがあります。javadoc から:

2 つの弦の間のレーベンシュタイン距離を求めます。

これは、1 つの文字列を別の文字列に変更するために必要な変更の数です。各変更は 1 文字の変更 (削除、挿入、または置換) です。

使用法:

int distance = StringUtils.getLevenshteinDistance(
    "some filename contains few words.txt",
    "some filename not contains few words.txt"
);

distanceあるパーセンテージで一致させるには、入力文字列の長さが異なる可能性があるため"cat"、どの文字列が「マスター」であるかを決定する必要があり"cataract"ます5。「90% 一致」とは何かを定義することも少し難しいです。私たちのcat例を見てください。文字列「cat」の 100% は「cataract」にありますが、まったく同じ文字列ではありません。ユースケースに応じて、これらのルールを決定する必要があります。

アップデート

「違い」が単語ベースである必要がある場合、単語境界で文字列を分割しMap、結果の単語から各単語のカウントまでを構築するのは比較的簡単です。各文字列に対して生成されたマップを比較すると、大まかな「類似性」の測定値が得られます。例えば:

public HashMap<String, Integer> countWords(String str) {
    HashMap<String, Integer> counts = new HashMap<String, Integer>();
    for(String s : str.split("\\s+")) {
        if(!s.isEmpty()) {
            if(counts.containsKey(s)) {
                counts.put(s, counts.get(s) + 1);
            } else {
                counts.put(s, 1);
            }
        }
    }
    return counts;
}

// ...

String s1 = "some filename contains few words.txt";
String s2 = "some filename not contains few words.txt";
HashMap<String, Integer> s1Counts = countWords(s1);
HashMap<String, Integer> s2Counts = countWords(s2);
// assume s1 is "master" string, count the total number of words
int s1Total = 0, s2Total = 0;
for(Integer i : s1Counts.values()) {
    s1Total += i;
}
// iterate over words in s1, find the number of matching words in s2
for(Map.Entry<String, Integer> entry : s1Counts.entrySet()) {
    if(s2Counts.containsKey(entry.getKey())) {
        if(s2Counts.get(entry.getKey()) >= entry.getValue()) {
            s2Total += entry.getValue();
        } else {
            s2Total += s2Counts.get(entry.getKey());
        }
    }
}
// result
System.out.println(s2Total + " out of " + s1Total + " words match.");
于 2012-06-20T07:30:14.917 に答える
1

Apache commons-text クラスJaroWinklerDistanceを見てみる価値があると思います

Find the Jaro Winkler Distance which indicates the similarity score between two CharSequences.
 distance.apply(null, null)          = IllegalArgumentException
 distance.apply("","")               = 0.0
 distance.apply("","a")              = 0.0
 distance.apply("aaapppp", "")       = 0.0
 distance.apply("frog", "fog")       = 0.93
 distance.apply("fly", "ant")        = 0.0
 distance.apply("elephant", "hippo") = 0.44
 distance.apply("hippo", "elephant") = 0.44
 distance.apply("hippo", "zzzzzzzz") = 0.0
 distance.apply("hello", "hallo")    = 0.88
 distance.apply("ABC Corporation", "ABC Corp") = 0.93
 distance.apply("D N H Enterprises Inc", "D & H Enterprises, Inc.") = 0.95
 distance.apply("My Gym Children's Fitness Center", "My Gym. Childrens Fitness") = 0.92
 distance.apply("PENNSYLVANIA", "PENNCISYLVNIA")    = 0.88
于 2018-09-26T20:16:35.387 に答える