2016-06-14 5 views
3

同様の文字列をリストから削除する効率的な方法は何でしょうか?類似の文字列をリストから削除するにはどうすればよいですか?

これらの(および他の)文字列からなるList<string>を考えてみましょう:

"SRS INVESTMENT MANAGEMENT、LLC"

"SRSの投資管理"

"Maplelaneキャピタル株式会社"

「Maplelaneキャピタル・リミテッド」

だから、私は何をする必要があるか「十分に類似」であり、文字列を削除しています。私の考えは、これは、リストのすべての文字列を大文字にしてから、最後に他の文字列のX文字を除くすべての文字列を削除することによって行う必要があるということです。結局のところ、実際に表現している実際の会社ごとに1つの文字列しか入っていないリストを私に残しておきたいのです。

私はこれをどのように達成することができますか?

+3

文字列にどれだけ近いかを測定し、特定のしきい値以下の文字列を削除するには、Levenshtein distanceを使用する必要があります。いくつかの並べ替えの全体的な最小をもたらす文字列で終わってほしい場合は、いくつかの素晴らしい作業をしたいかもしれません。これは些細なことではありません。 – Jashaszun

+0

リスト内のアイテム数(約)? – spender

+2

リストのすべての名前にアメリカの標準英語26文字のアルファベットの表記が含まれていることを保証していますか?たとえば、「チューリッヒ金融サービス」を「チューリッヒ・ファイナンシャル・サービシズ・リミテッド」と合致させる必要がある場合、あなたはより困難な問題を抱えています。これらの文字列は、2番目の文字に不一致があります。 –

答えて

1

2つの文字列が等しいかどうかを判断するロジックをカプセル化するIEqualityComparerを作成することをお勧めします。

たとえば、あなたがSOUNDEXとレーベンシュタインをミックスして一致したい場合

public class CompanyNameComparer : IEqualityComparer<string> 
{ 

    public bool Equals(string x, string y) 
    { 
     if (x == null && y == null) 
     { 
      return true; 
     } 
     if (x == null || y == null) 
     { 
      return false; 
     } 

     var src1 = FormatString(x); 
     var src2 = FormatString(y); 

     if (src1 == src2) 
     { 
      return true; 
     } 

     var difference = CalcLevenshteinDistance(src1, src2); 

     // arbitrary number you will need to find what works 
     return difference < 7; 
    } 

    private string FormatString(string source) 
    { 
     return source.Trim().ToUpper(); 
    } 

    // code taken from http://stackoverflow.com/a/9453762/1798889 
    private int CalcLevenshteinDistance(string a, string b) 
    { 
     // code not included 
    } 

    public int GetHashCode(string obj) 
    { 
     return Soundex(obj).GetHashCode(); 
    } 

    private string Soundex(string data) 
    { 
     // code not included 
    } 
} 

のようなものであるかもしれないことが主なポイントではないので、私はすべてのコードが含まれていませんでした。 SoundExとLevenshteinが動作するのか、それとも別のものにする必要があるのか​​、あなただけが知っています。しかし、それを調整する必要がある場合、それを自分のクラスに入れれば、変更する必要がある場所は1つだけです。

次に、LinqまたはHashSetのいずれかで一意のリストを取得できます。データがリストの変数の名前であると仮定します。

var uniqueEnumerable = data.Distinct(new CompanyNameComparer()); 
var uniqueSet = new HashSet<string>(data, new CompanyNameComparer()); 
2

明白な略語を完全な単語に置き換えてから空白を削除するルーチンを作成することから始めます。良いニュースは、会社の家は会社名について非常に厳しい規則を持っているということです。たとえば、 'Band C Ltd'が既に存在する場合、「B & C Ltd」という会社を持つことはできません。 その後、LevenshteinsやSoundexなどのアルゴリズムのマッチングについて考える必要があります。

+0

私は略語などの置き換えを実験しましたが、置き換えられるもののリストは広範になりますが、動作するようです。@CharlesNRiceによって提案されたソリューションを使用する前に、これは良い出発点であると判断します。 –

+0

一致する会社名の場合は、アルゴリズムに非常に注意する必要があります。私たちはビジネスマッチングソフトウェアの開発に長年を費やしており、すべてのクライアントには異なる要件があります。私の最善のアドバイスは、個々のプロジェクトのための適切なバランスを取るアプローチを見つけるまで、結果を目の当たりにすることです。 – JonnyCab

関連する問題