2015-04-10 2 views
1

Я пишу программу на C# для чтения из файла и выводя в файл csv все уникальные слова и количество вхождений в файле для каждого слова. Моя проблема в том, что когда я пытаюсь запустить свою программу, я никогда не выхожу из своего цикла while, который идет по строкам.Проблема с бесконечным циклом при чтении из файла

public override List<WordEntry> GetWordCount() 
{ 
     List<WordEntry> words = new List<WordEntry>(); 
     WordEntry wordEntry = new WordEntry(); 
     //string[] tokens = null; 
     string line, temp, getword; 
     int count = 0, index = 0; 
     long number; 

     while ((line = input.ReadLine()) != null) 
     { 
      if (line == null) 
       Debug.Write("shouldnt happen"); 
      char[] delimit = { ' ', ',' }; 
      string[] tokens = line.Split(delimit); 

      if (words.Count == 0) 
      { 
       wordEntry.Word = tokens[0]; 
       wordEntry.WordCount = 1; 
       words.Add(wordEntry); 
      }//end if 

      for (int i = 0; i < tokens.Length; i++) 
      { 
       for (int j = 0; j < words.Count; j++) 
       { 
        if (tokens[i] == words[j].Word) 
        { 
         number = words[j].WordCount; 
         number++; 
         getword = words[j].Word; 
         wordEntry.WordCount = number; 
         wordEntry.Word = getword; 
         words.RemoveAt(j); 
         words.Insert(j, wordEntry); 
        }//end if 
        else 
        { 
         wordEntry.Word = tokens[i]; 
         wordEntry.WordCount = 1; 
         words.Add(wordEntry); 
        }//end else 
       }//end for 
      }//end for 
     }//end while 
     return words; 
} 

Он застревает в цикле while, как будто он никогда не доходит до конца файла. Файл составляет 2,6 МБ, чтобы он мог довести его до конца.

+0

Как долго вы можете ждать? Thats ужасно большой файл ... – BradleyDotNET

+0

@BradleyDonNET Да, я принял это во внимание. Я ждал много времени. Я могу попробовать еще раз и подождать 10 минут, чтобы узнать, не в конце концов ли это догоняет. Я просто не чувствую, что это должно занять так много времени. – saboehnke

+1

Вместо вашего 'List ' почему бы не использовать 'Dictionary ', чтобы быстро проверить, не видели ли вы это слово, а не перебираете все слова, которые вы уже видели. – juharr

ответ

3

Вот как вы можете переписать свой код, чтобы использовать словарь.

var words = new Dictionary<string,int>(); 

while ((line = input.ReadLine()) != null) 
{ 
    if (line == null) 
     Debug.Write("shouldnt happen"); 
    char[] delimit = { ' ', ',' }; 
    string[] tokens = line.Split(delimit); 

    foreach (var word in tokens) 
    { 
     if(words.ContainsKey(word)) 
      words[word]++; 
     else 
      words.Add(word, 1); 
    } 
} 

Это уменьшает сложность кода, потому что словарь содержит поиск по O (1).

EDIT

Вы можете конвертировать словарь в List<WordEntry> как это.

return words 
    .Select(kvp => new WorkEntry 
     { 
      Word = kvp.Key, 
      WordCount = kvp.Value 
     }) 
    .ToList(); 
+0

Хорошо выглядит. Я думаю, что вы можете пропустить вызов слова. ContainsKey и просто использовать индекс indexer всегда, чтобы всегда ++ – Biscuits

+0

@juharr Я рассмотрю это. Я ценю вашу помощь. Моя единственная проблема с рассмотрением этого - это предварительно написанный метод, который я должен написать для говядины. Он должен вернуть список <>. Возможно ли это, не разбивая словарь на два разных списка? – saboehnke

+0

возвращение слов.Keys.ToList() – Biscuits

1

Я предполагаю, что на самом деле ваш код не выходит из «for (int j = 0; j < words.Count; j ++)», потому что новые элементы сохраняются в списке слов.

Смежные вопросы