2017-02-24 6 views
0

Ich muss ein Frequenzanalyse-Konsolenprogramm mit C# machen. Es muss die 10 häufigsten Buchstaben aus einer Textdatei anzeigen. Ich habe es geschafft, die ersten 10 vom Programm gelesenen Buchstaben und die Häufigkeit jedes Zeichens anzuzeigen. Ich weiß jedoch nicht, wie man das Wörterbuch sortiert. Dies ist der Code, den ich bisher habe.Wie sortiere ich ein Wörterbuch in C# .net

Ich muss dem Benutzer auch die Option zur Frequenzanalyse im sensitiven Modus geben (wie es jetzt ist) und Groß-/Kleinschreibung beachten. Hilfe mit diesem Problem wird ebenfalls geschätzt. Danke!

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 Gehen Sie durch diesen Link! – Sameer

+0

Sie können kein 'Dictionary' sortieren. Es gibt kein Konzept der Ordnung. Was Sie tun können, ist, das Wörterbuch in eine Liste/Enumerable zu konvertieren und das zu sortieren, wie es @aquinas getan hat. –

Antwort

0

Es wäre einfacher, den tatsächlichen Dictionary-Typen in C# verwenden hier, anstatt ein Array:

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

Sie einen Schlüssel hinzufügen, wenn es nicht bereits vorhanden ist (und einen Wert von einfügen 1), oder Sie erhöhen den Wert, wenn er existiert. Dann können Sie die Schlüssel Ihres Wörterbuchs als eine Liste herausziehen und sie sortieren, indem Sie iterieren, um die Werte zu finden. Wenn Sie die Groß- und Kleinschreibung nicht beachten, konvertieren Sie nur Groß- und Kleinschreibung, bevor Sie sie in das Wörterbuch einfügen.

Hier ist der MSDN-Seite für die Beispiele für Wörterbuch: https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx#Examples

3

Wenn alles, was Sie tun möchten, ist Frequenzen zu finden, Sie wollen keine Wörterbücher, sondern ein Linq. Solche Aufgaben sind solche Linq für entworfen wurde:

... 
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

I @Dmitry Bychenko Antwort mögen, weil es sehr knapp ist. Wenn Sie jedoch eine sehr große Datei haben, ist diese Lösung möglicherweise nicht optimal für Sie. Der Grund dafür ist, dass diese Lösung die gesamte Datei in den Speicher lesen muss, um sie zu verarbeiten. Also, in meinen Tests habe ich bis zu 1GB Speicherverbrauch für eine 500MB-Datei bekommen. Die Lösung unten, obwohl nicht ganz so knapp, verwendet konstanten Speicher (im Grunde 0) und läuft so schnell oder schneller als die Linq-Version in meinen Tests.

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)); 
Verwandte Themen