2016-06-17 3 views
-1

質問:私は長い文字列を持っており、その文字列の下にあるすべてのサブ文字列の出現回数を調べ、すべてのサブ文字列のリストとその数を出力する必要があります(if countは> 1)をカウントする。Count C#

例:

String = "abcdabcd" 

結果:

Substrings  Count 
abcd   2 
abc    2 
bcd    2 
ab    2 
bc    2 
cd    2 
a    2 
b    2 
c    2 
d    2 

問題:私の文字列が5000文字の長さにすることができ、私はこれを達成するための効率的な方法を見つけることができないです(効率性は非常に重要ですアプリケーション用)

アルゴリズムが存在するか、マルチスレッド化が可能ですか?助けてください。使用

+1

してください、*接尾辞木を見てみましょう*または/および*接尾辞配列* https://en.wikipedia.org/ wiki/Suffix_array –

+0

@DmitryBychenko:私は接尾辞ツリーと接尾辞配列で試しましたが、すべての下位文字列を見つけるために接尾辞ツリーから可能な方法はありません。 しかし、サブストリングが入力として与えられた場合、サフィックスツリーを介してその出現回数を非常に効率的に見つけることができます。 –

+0

[文字列のリスト内で共通の文字列を検索する]の可能な複製(http://stackoverflow.com/questions/13509277/find-a-common-string-within-a-list-of-strings) – Clint

答えて

0

例:Find a common string within a list of strings

void Main() 
{ 
    "abcdabcd".getAllSubstrings() 
     .AsParallel() 
     .GroupBy(x => x) 
     .Select(g => new {g.Key, count=g.Count()}) 
     .Dump(); 
} 

// Define other methods and classes here 

public static class Ext 
{ 
    public static IEnumerable<string> getAllSubstrings(this string word) 
    { 
     return from charIndex1 in Enumerable.Range(0, word.Length) 
      from charIndex2 in Enumerable.Range(0, word.Length - charIndex1 + 1) 
      where charIndex2 > 0 
      select word.Substring(charIndex1, charIndex2); 
    } 
} 

が生成されます

a 2 
dabc 1 
abcdabc 1 
b 2 
abc 2 
dabcd 1 
bc 2 
bcda 1 
abcd 2 
ab 2 
bcdab 1 
cdabc 1 
abcda 1 
d 2 
bcdabc 1 
dab 1 
bcd 2 
abcdab 1 
c 2 
bcdabcd 1 
abcdabcd 1 
cd 2 
da 1 
cdab 1 
cda 1 
cdabcd 1 
+0

長さが1000文字の文字列にはうまくいきますが、文字列の長さが2000を超えるとメモリ不足例外が発生します。 "select word.Substring(charIndex1、charIndex2);" 提案がありますか? –

+0

@NancyGarg大きな文字列は、必然的にOOMエラーを引き起こします。多くの文字列は、すばやく多くの配列を作成します。私の提案は一般的な原則をとることですが、ストリングを扱うためには別の構造を使用してください。ストリングビルダー/ロールは別のものです。 – Clint

+1

32ビットコンパイラを64ビットに変更しました。以前のアプローチと比較しても非常に効率的です。感謝のトン.. :) –