C # реализация словаря для подсчета вхождений слов возвращает повторяющиеся слова в выводе - PullRequest
3 голосов
/ 30 марта 2011

Недавно я сделал небольшое приложение для чтения текстового файла с текстами песен, а затем с помощью словаря вычисляю, сколько раз встречается каждое слово.Однако по какой-то причине я нахожу в выходных данных случаи, когда одно и то же слово встречается несколько раз со счетом 1 вместо того, чтобы быть добавленным к исходному счету слова.Код, который я использую, выглядит следующим образом:

StreamReader input = new StreamReader(path);
        String[] contents = input.ReadToEnd()
                                            .ToLower()
                                            .Replace(",","")
                                            .Replace("(","")
                                            .Replace(")", "")
                                            .Replace(".","")
                                            .Split(' ');
        input.Close();
        var dict = new Dictionary<string, int>();
        foreach (String word in contents)
        {
            if (dict.ContainsKey(word))
            {
                dict[word]++;
            }else{
                dict[word] = 1;
            }
        }
        var ordered = from k in dict.Keys
                              orderby dict[k] descending
                              select k;
        using (StreamWriter output = new StreamWriter("output.txt"))
        {
            foreach (String k in ordered)
            {
                output.WriteLine(String.Format("{0}: {1}", k, dict[k]));
            }
            output.Close();
            timer.Stop();
        }

Текстовый файл, который я ввожу, находится здесь: http://pastebin.com/xZBHkjGt (это тексты 15 лучших рэп-песен, если выЛюбопытно) Выходные данные можно найти здесь: http://pastebin.com/DftANNkE Быстрый Ctrl-F показывает, что «девушка» встречается в выходных данных как минимум 13 раз.Насколько я могу судить, это одно и то же слово, если только нет разницы в значениях ASCII.Да, там есть несколько примеров с нечетными символами вместо апострофа, но я буду беспокоиться об этом позже.Мой приоритет - выяснить, почему одно и то же слово учитывается 13 раз как разные слова.Почему это происходит, и как мне это исправить?Любая помощь очень ценится!

Ответы [ 4 ]

9 голосов
/ 30 марта 2011

Другой способ - разделить не слова.

var lyrics = "I fly with the stars in the skies I am no longer tryin' to survive I believe that life is a prize But to live doesn't mean your alive Don't worry bout me and who I fire I get what I desire, It's my empire And yes I call the shots".ToLower();
var contents = Regex.Split(lyrics, @"[^\w'+]");

Также вот альтернативный (и, вероятно, более неясный) цикл

int value;
foreach (var word in contents)
{
    dict[word] = dict.TryGetValue(word, out value) ? ++value : 1; 
}
dict.Remove("");
4 голосов
/ 30 марта 2011

Если вы заметили, повторяющиеся вхождения появляются в строке после слова, которое, по-видимому, не имеет счет.

Вы не удаляете символы новой строки, поэтому em\r\ngirl рассматривается как другое слово.

1 голос
/ 30 марта 2011

Добавить Trim к каждому слову:

foreach (String word in contents.Select(w => w.Trim()))
1 голос
/ 30 марта 2011
String[] contents = input.ReadToEnd()
    .ToLower()
    .Replace(",", "")
    .Replace("(", "")
    .Replace(")", "")
    .Replace(".", "")
    .Split("\r\n ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

Работает лучше.

...