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

I spent quite a while to figure out this Linq which will result in the exact same array you want:

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 回答
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 回答