2

プログラムに StreamReader を使用してテキスト ファイルを読み込んでいます。文字列内の各文字の頻度を配列に記録する必要があります (インデックス 0 は A など)。これに対する最も簡単なアプローチは何ですか?

編集:完全に間違っていることに気付くまで、私はもともとこれを持っていました。

int counter = 0;
int[] freq = new int[26]; // create frequency array

// counts frequency
while (counter < inValue.Length)
{
      int A = 65; // ASCII value for "A"
      char x = char.Parse(inValue.Substring(counter, 1)); // get individual characters from string
       int s = (int)x; // cast character to integer value

       if (s == A + counter)
             freq[counter]++;

             counter++;
 }

inValue は、StreamReader がプログラムに読み込むテキスト ファイルです。

4

4 に答える 4

6
var freqs = File.ReadAllText("myfile.txt")
                    .Where(c => Char.IsLetter(c))
                    .GroupBy(c => c)
                    .ToDictionary(g => g.Key, g => g.Count());

これにより、文字の辞書とその数がわかります。

アップデート:

大文字と小文字を区別しないカウントが必要な場合は、GroupByを変更するだけです。

.GroupBy(c => Char.ToUpper(c)) // instead of .GroupBy(c => c)

そして、私の意見では、この場合、「カウント」が属する文字はインデックスによって暗示されるだけではないため、辞書は配列よりも優れています。代わりに、それは明示的なキーです。これにより、文字をインデックスに変換する必要がないため、ルックアップが簡単になります。さらに、これにより、国際化サポートを追加する際の柔軟性が高まります。ただし、どうしても配列が必要な場合は、簡単な変更です。

var freqs = File.ReadAllText("myfile.txt")
                    .Where(c => Char.IsLetter(c))
                    .GroupBy(c => c)
                    .OrderBy(g => g.Key) 
                    .Select(g => g.Count())
                    .ToArray()
于 2012-11-04T05:45:27.337 に答える
1

このようなものを試すことができます。これは私にとってはうまくいきましたが、StreamReaderを使用しませんでした:-

   int[] c = new int[(int)char.MaxValue];

string s = File.ReadAllText("text.txt");

foreach (char t in s)
{
    c[(int)t]++;
}

for (int i = 0; i < (int)char.MaxValue; i++)
{
    if (c[i] > 0 &&
    char.IsLetterOrDigit((char)i))
    {
    Console.WriteLine("Letter: {0}  Frequency: {1}",(char)i, c[i]);
    }
}
于 2012-11-04T05:38:48.960 に答える
0

'A' から 'Z' までの文字のみを数えたいと仮定すると、コードにいくつかの変更を加えるだけで機能します。

int counter = 0;
int[] freq = new int[26]; // create frequency array

// counts frequency
while (counter < inValue.Length)
{
    char c = invalue[counter];
    if (c >= 'A' && c <= 'Z')
    {
        ++freq[(int)c - 65]
    }
    ++counter;
}

小文字も数えたい場合は、ループの最初の行を次のように変更します。

char c = char.ToUpper(invalue[counter]);
于 2012-11-04T06:01:09.200 に答える
0

このLinqを理解するのにかなりの時間を費やしました。これにより、必要な配列とまったく同じ結果が得られます。

int[] occurance = File.ReadAllText("myfile.txt")
                  .Where(c => char.IsLetter(c))
                  .Select(c => (int)char.ToUpperInvariant(c) - 65)
                  .GroupBy(a => a)
                  .ToDictionary(a => a.Key, a => a.Count())
                  .OrderBy(a => a.Key)
                  .Select(a => a.Value)
                  .ToArray();
于 2012-11-04T06:13:24.917 に答える