1

キャップを考慮せずに、文字列内の各文字の出現をカウントする簡単なメソッドを作成しました。

static List<int> charactercount(string input)
        {
            char[] characters = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
            input = input.ToLower();

            List<int> counts = new List<int>();
            foreach (char c in characters)
            {
                int count = 0;
                foreach (char c2 in input) if (c2 == c)
                    {
                        count++;
                    }

                counts.Add(count);
             }

            return counts;

        }

これを行うためのよりクリーンな方法はありますか(つまり、アルファベットのすべての文字を保持するための文字配列を作成せずに)、数字、他の文字、大文字なども考慮に入れますか?

4

4 に答える 4

2

Dictionary<string,int>概念的には、カウントを返したいと思います。明示的に0を数えるのではなく、省略して、文字が0回出現することを知っていても問題ないと思います。これは、LINQを介して行うことができます。@Odedは、その方法について良いスタートを切った。あなたがする必要があるのは、Select()をに置き換えることだけですToDictionary( k => k.Key, v => v.Count() )。大文字と小文字を区別しないグループ化の実行に関する彼の回答に関する私のコメントを参照してください。注:キャラクターの文化的な違いを気にするかどうかを決定し、ToLowerそれに応じて方法を調整する必要があります。

LINQなしでこれを行うこともできます。

public static Dictionary<string,int> CountCharacters(string input)
{
     var counts = new Dictionary<char,int>(StringComparer.OrdinalIgnoreCase);

     foreach (var c in input)
     {
          int count = 0;
          if (counts.ContainsKey(c))
          {
              count = counts[c];
          }
          counts[c] = counts + 1;
     }

     return counts;
}

が必要な場合は、大文字と小文字を区別しない文字比較子を作成し、それを必要なタイプの辞書のDictionary<char,int>として使用することで、簡単に行うことができます。例では簡単にするためにIEqualityComparer<T>使用しました。string

繰り返しになりますが、カルチャを処理する方法と一致するように比較子のタイプを調整します。

于 2012-12-22T19:33:22.377 に答える
1

GroupByおよびを使用するSelect

aString.GroupBy(c => c).Select(g => new { Character = g.Key, Num = g.Count() })

返される匿名型リストには、各文字とそれが文字列に表示される回数が含まれます。

次に、で定義された静的メソッドを使用して、任意の方法でフィルタリングできますChar

于 2012-12-22T19:12:38.120 に答える
0

入力をループするだけでなく、範囲azをループしているため、コードは少し遅くなります。

文字を数えるだけでよい場合(コードが示唆しているように)、それを行う最も速い方法は次のとおりです。

int[] CountCharacters(string text)
{
    var counts = new int[26];

    for (var i = 0; i < text.Length; i++)
    {
        var charIndex - text[index] - (int)'a';
        counts[charIndex] = counts[charindex] + 1;
    }

    return counts;
}  

文字が範囲内にあることを確認し、必要に応じて小文字に変換するなどの機能を追加する必要があることに注意してください。そうしないと、このコードで例外がスローされる可能性があります。追加するためにそれらを残しておきます。:)

于 2012-12-22T19:36:23.767 に答える
0

回避するための+Ranの回答に基づくIndexOutOfRangeException

static readonly int differ = 'a';
int[] CountCharacters(string text) {
    text = text.ToLower();
    var counts = new int[26];

    for (var i = 0; i < text.Length; i++) {
        var charIndex = text[i] - differ;
        // to counting chars between 'a' and 'z' we have to do this:
        if(charIndex >= 0 && charIndex < 26)
            counts[charIndex] += 1;
    }
    return counts;
}

実際に使用Dictionaryしたり、LINQ文字をカウントしたり、低レベルの配列を操作したりする場合は、十分に最適化されていません。

于 2012-12-22T20:28:57.993 に答える