2012-09-12 14 views
6

文字列から一意の文字を抽出したい。たとえば、 - 'AAABBBBBCCCCFFFFGGGGGDDDDJJJJJJ'が返されます'ABCFGDJ'文字列から一意の文字を取得するには?

私は以下のコードを試しましたが、今は最適化したいと思います。 誰かが知っていることをお勧めします。

static string extract(string original) 
{ 
     List<char> characters = new List<char>(); 
     string unique = string.Empty; 
     foreach (char letter in original.ToCharArray())  
     { 
      if (!characters.Contains(letter)) 
      {  
        characters.Add(letter); 
       }    
      } 
     foreach (char letter in characters) 
     { 
       unique += letter;  
     }  
    return unique; 
} 
+4

"私はそれを最適化したい" - なぜですか?プロファイリング中に見つけたパフォーマンスのボトルネックですか? – Oded

+0

パフォーマンスのボトルネックではありませんが、私が得ることができれば、より最適なソリューションを探していました。 –

+1

@Oded Rahulが正しいです。ループで繰り返し文字列連結を使用すると、パフォーマンスが低下することはよく知られています。これは 'StringBuilder'のもっとも重要な使用例の1つです。また、 'List 'の 'Contains'メソッドを使用するのは比較的非効率的です。これは 'HashSet 'の最も重要なユースケースの1つです。コードは 'List 'の代わりに 'HashSet 'を使用し、 'StringBuilder'に' unique'を変更する方がはるかに効率的です。しかし、linqの方が優れています。効率的に動作します。*コード化するのがより簡単で簡単です。 – phoog

答えて

13

私はこれが高速であるかどうかを知る、しかし確実に短く

string s = "AAABBBBBCCCCFFFFGGGGGDDDDJJJJJJ"; 
var newstr = String.Join("", s.Distinct()); 
+3

これは内部的にHashSetを使用するので、O(n^2)のアプローチよりも速いO(n)です – BrokenGlass

+2

"AAABBBAAAA"を "AB"に変換しませんか?質問はそれが望ましい行動であるかどうかを定義しない。直観的には、「ABA」が正しい答えになるようです。 – zeFrenchy

+0

@DominiqueJacquel上記のコードは、OPの質問で「抽出」と同じことをします –

2

どの程度

var result = string.Join("", "AAABBBBBCCCCFFFFGGGGGDDDDJJJJJJ".Distinct()); 

はありませんが、あなたがSystem.Linq名前空間が含まれていることを確認してください。

5

別のLINQのアプローチが、string.Joinを使用していない:

var result = new string(original.Distinct().ToArray()); 

私は正直に速くなり、文字列の作成にどのアプローチを知りません。 がStringBuilderに追加する前に各要素を文字列に内部的に変換するかどうか、またはそれを回避するためにいくつかのよく知られた種類のカスタムサポートがあるかどうかによって決まるでしょう。

+1

男、LINQはクールです。これは、データを扱うまったく新しい方法のようなものです。 – user1477388

+0

@ user1477388 ...はい。パーティーに参加してください! – spender

2

私はこれが役に立てば幸いこの

string str = "AAABBBBBCCCCFFFFGGGGGDDDDJJJJJJ"; 
string answer = new String(str.Distinct().ToArray()); 

を試してみてください。

2

"AAABBBAAA"が "ABA"を返す必要がある場合は、次のようにします。非常に速くはありません。

List<char> no_repeats = new List<char>(); 
no_repeats.Add(s[0]); 
for (int i = 1; i < s.Length; i++) 
{ 
    if (s[i] != no_repeats.Last()) no_repeats.Add(s[i]); 
} 
string result = string.Join("", no_repeats); 
+0

ドミニク: - 私の出力は「AB」だけにしたい。その場合は –

+0

@ L.Bより上のソリューションがあります – zeFrenchy

関連する問題