2017-02-24 38 views
0

我需要使用c#製作頻率分析控制檯程序。它必須顯示文本文件中最常用的10個字母。我設法顯示程序讀取的前10個字母以及每個字符的頻率。然而,我不知道如何對字典進行排序。這是迄今爲止的代碼。如何在C#中對字典進行排序.net

我還必須爲用戶提供在區分大小寫的情況下進行頻率分析的選項(與現在一樣)並且不區分大小寫。這個問題的幫助也將不勝感激。謝謝!

static void Main(string[] args) 
    { 
     // 1. 
    // Array to store frequencies. 
    int[] c = new int[(int)char.MaxValue]; 

     // 2. 
     // Read entire text file. 
     // string root = Server.MapPath("~"); 
     // string FileName = root + "/App_Data/text.txt"; 

     //string s = File.ReadAllText(FileName); 

     foreach (string line in  File.ReadLines(@"c:\Users\user\Documents\Visual Studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\App_Data\text.txt", Encoding.UTF8)) { 

      var fileStream = new FileStream(@"c:\Users\user\Documents\Visual Studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\App_Data\text.txt", FileMode.Open, FileAccess.Read); 
     using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) 
     { 
       string line2; 
       while ((line2 = streamReader.ReadLine()) != null) 
      { 
       // process the line 


       // 3. 
       // Iterate over each character. 
       foreach (char t in line) 
       { 
        // Increment table. 
        c[(int)t]++; 
       } 

        // 4. 
        // Write all letters found. 
        int counter = 0; 
        for (int i = 0; i < (int)char.MaxValue; i++) 
       { 


         if (c[i] > 0 && counter < 11 && 
         char.IsLetterOrDigit((char)i)) 
        { 
          ++counter; 
          Console.WriteLine("Letter: {0} Frequency: {1}", 
          (char)i, 
          c[i]); 
        } 
       } 
      } 
     } 
      Console.ReadLine(); 

    } 

    } 
+0

https://www.dotnetperls.com/sort-dictionary查看此鏈接! – Sameer

+0

你不能排序'Dictionary'。沒有秩序的概念。你可以做的是將字典轉換爲List/Enumerable並對其進行排序,如@aquinas已完成。 –

回答

0

它會更容易在這裏使用C#中的實際字典類型,而不是一個數組:

Dictionary<char, int> characterCountDictionary = new Dictionary<char, int>(); 

您添加的關鍵,如果不存在的話(和插入的值1),或者如果它存在,則增加該值。然後,您可以將列表中的鍵作爲列表提取出來,並對它們進行排序,迭代以找到值。如果您不區分大小寫,則只需將所有大寫字母轉換爲小寫字母,然後再插入字典。

下面是用於字典的例子在MSDN頁:https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx#Examples

3

如果你想要做的是找到的頻率,你不希望任何字典,而是的LINQ。這些任務是Linq設計的:

... 
using System.Linq; 
... 

static void Main(string[] args) { 
    var result = File 
    .ReadLines(@"...", Encoding.UTF8) 
    .SelectMany(line => line)    // string into characters 
    .Where(c => char.IsLetterOrDigit(c)) 
    .GroupBy(c => c) 
    .Select(chunk => new { 
     Letter = chunk.Key, 
     Count = chunk.Count() }) 
    .OrderByDescending(item => item.Count) 
    .ThenBy(item => item.Letter)   // in case of tie sort by letter 
    .Take(10) 
    .Select(item => $"{item.Letter} freq. {item.Count}"); // $"..." - C# 6.0 syntax 

    Console.Write(string.Join(Environment.NewLine, result)); 
} 
0

我喜歡@Dmitry Bychenko的回答,因爲它非常簡潔。但是,如果你有一個非常大的文件,那麼這個解決方案可能不適合你。原因是,該解決方案必須將整個文件讀入內存才能處理它。所以,在我的測試中,我爲500MB文件起了大約1GB的內存使用量。下面的解決方案雖然不太簡潔,但它使用的是恆定內存(基本上爲0),並且運行速度比我的測試中的Linq版本更快或更快。

Dictionary<char, int> freq = new Dictionary<char, int>(); 

using (StreamReader sr = new StreamReader(@"yourBigFile")) { 
    string line; 
    while ((line = sr.ReadLine()) != null) { 
     foreach (char c in line) { 
      if (!freq.ContainsKey(c)) { 
       freq[c] = 0; 
      } 
      freq[c]++; 
     } 
    } 
} 

var result = freq.Where(c => char.IsLetterOrDigit(c.Key)).OrderByDescending(x => x.Value).Take(10); 
Console.WriteLine(string.Join(Environment.NewLine, result)); 
相關問題