Zusatzaufgaben (sort,ToLower,"Leerzeichen") aus Programm aus dem Vorpost!



  • Ich habe bereits mit Hilfe einiger User und in alleingier Recherche ein Programm erstellt, welches Worte aus einer Datei ausliest, diese Zählt und dann ausgibt mit dem Zähler, wie oft das Wort vor kommt.

    Dazu habe ich jetzt weitere Aufgaben bekommen:
    1. Sortiere die ausgegebenen Wörter
    2. Sorge dafür, dass Groß und Kleinschriebung ignoriert wird
    3. Leerzeichen und Sonderzeichen ausfiltern

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    
    //Zu ermittlen ist die jeweilige Anzahl aller Woerter in der ausgelesenen Datei
    
    class Dateiausgabe
    {
        public static void Main()
        {
            //-----------------------------------------------------------------------
            //Oeffnen der entsprechenden Datei
            StreamReader rd = new StreamReader("d:\\heinemann\\Kurzgeschichte.txt");
            string line;
    
            //-----------------------------------------------------------------------
            /*Aufsplittung nach den betreffenden Satzzeichen, um aus einem Textstring mehrere Wortstrings zu fertigen.
            Als Array, da jede Zeile einzeln betrachtet werden muss, sonst wird immer nur die erste betrachtet*/
    
            Dictionary<string, int> zaehler = new Dictionary<string, int>();
    
            while ((line = rd.ReadLine()) != null)
            {
                string[] words = line.Split(' ', ',', '.', '?', '!', ':', ';');
    
                //-----------------------------------------------------------------------
                //Ausgabe der Anzahl der Woerter!
                for (int i = 0; i < words.Length; i++)
                {
                    string wort = words[i];
    
                        if (!zaehler.ContainsKey(wort))
                        {
                            zaehler[wort] = 1;
                        }
                        else
                        {
                            zaehler[wort] = zaehler[wort] + 1;
                        }  
                }
            }
            rd.Close();
    
            //-----------------------------------------------------------------------
            //Ausgabe der Wörter, beziehungsweise der Anzahl ebendieser!
            Console.WriteLine("Ausgabe:");
            foreach (string wort in zaehler.Keys)
            {
                Console.WriteLine(" {0} {1}", wort, zaehler[wort]);
            }
    
            Console.ReadLine();
        }
    }
    

    Soweit läuft das Programm ohne die Aufgaben.
    Nun soll ich diese mit einbringen.
    Ich habe mir Gedanken gemacht, wie es ungefähr aussehen soll, aber ich weiß nicht, wo ich die neuen Ansätze genau einfügen soll und ob eventuell kombiniert werden muss:

    Sortierung der Wörter nach Alphabet:

    //-----------------------------------------------------------------------
            //Sortierung der Wörter nach Alphabet!
            List<string> worte2 = new List<string>();
    
            worte2.Add(line);
            worte2.Sort();
    

    Ist habe eine neue Bezeichnung gewählt, wobei die Frage ist, muss ich das überhaupt?

    Groß und Kleinschriebung:

    //-----------------------------------------------------------------------
            //Groß- und Kleinschriebung!
            string klwort;
    
            wort.ToLower();
    

    Gehört das separiert oder möglicherweise irgendwo zwischengeschoben, und/oder in eine Schleife implementiert?

    //-----------------------------------------------------------------------
    //Sonderzeichenausfilterung!
            //Hierbei wollte ich eventuell die Schleife so modifizieren, dass sie nur läuft, wenn gerade kein Zeichen vorhanden ist. Geht das dann so?
    
              for (int i = 0; i < words.Length; i++)
                {
                    string wort = words[i];
                        if (!zaehler.ContainsKey(' ', ',', '.', '?', '!', ':', ';');
                        {
                           if (!zaehler.ContainsKey(wort))
                           {
                               zaehler[wort] = 1;
                           }
                           else
                           {
                               zaehler[wort] = zaehler[wort] + 1;
                           }  
                        } 
               }
    


  • beginner_1234 schrieb:

    if (!zaehler.ContainsKey(wort))
    {
        zaehler[wort] = 1;
    }
    

    Soweit läuft das Programm ohne die Aufgaben.

    Glaub ich nicht. Es baut zwar fliegt dir aber mit einer Exception um die Ohren.


  • Administrator

    David W schrieb:

    Glaub ich nicht. Es baut zwar fliegt dir aber mit einer Exception um die Ohren.

    Wieso? Man kann über den Indexer neue Einträge eintragen.
    http://msdn.microsoft.com/en-us/library/9tee9ht2.aspx

    The value associated with the specified key. If the specified key is not found, a get operation throws a KeyNotFoundException, and a set operation creates a new element with the specified key.

    @beginner_1234,
    Schau dir mal die Klasse StringComparer an. Hat auch ein nettes Beispiel dabei 😉

    Grüssli



  • Oh, das ist ja völlig an mir vorbei gegangen ^^ Ich hab immer mit Add hinzugefügt.
    Gratz.



  • Also jetzt nur mal fürs sortieren habe ich es so versucht, aber die Ausgabe bleibt in unalphabetischer Reihenfolge, wieso ist das so?

    for (int i = 0; i < words.Length; i++)
                {
                    string wort = words[i];
    
                    List<string> worte2 = new List<string>();
    
                    worte2.Add(wort);
                    worte2.Sort();
    
                    if (!zaehler.ContainsKey(wort))
                    {
                        zaehler[wort] = 1;
                    }
                    else
                    {
                        zaehler[wort] = zaehler[wort] + 1;
                    }
                }
    


  • worte2 ist innerhalb der for schleife, dh bei jedem durchlauf wird sie neu erstellt.
    Was gibst du aus? worte2 bestimmt nicht 😉
    Schon das zweite mal das du mit dem scope durcheinander gerätst.

    Es würde auch reichen die Liste einmal am ende zu Sortieren sobald alle Worte enthalten sind.

    Tipp: Du benutzt ja zum zählen der Worte ein Dictionary, es gibt auch eine SortedList 😉 dann sind alle Worte direkt sortiert sobald du es hinzufügst.
    Du kannst das Sortierverhalten dann auch beeinflussen (wegen dem Lower).



  • OK, also ich gebe auf jeden Fall die strings aus dem Array Wort und dahinter die Werte für den Zähler aus (keys). Ist es demnach falsch mit worte2 zu arbeiten oder gehört das einfach nur woanders hin? Wenn es woanders hingehört, dann wohl zwischen Schleife und Ausgabe oder? Den ich muss das ja vor der Asugabe sortieren.



  • worte2 macht so wie du es dort hast keinen sinn, da es wie du bestimmt erkennst nur in der for schleife bekannt ist, du fügst dann ein wort hinzu, sortierst das eine Wort, und beim nächsten Durchlauf fängt es wieder von vorne an.

    Das Dictionary "zähler" wird nicht verändert. Logisch das wenn du das "zähler" dann ausgibst das sich nichts verändert hat.

    Das könntest du so machen indem du dir alle Worte vor der Ausgabe in eine Liste holst, diese Sortierst und dann ausgibst:

    // Ungetestet hier im Forum getippt
    var words = new List<string>(zähler.Keys);
    words.Sort(SortLower);
    foreach (var word in words)
    {
        var pair = zähler[word];
        Console.WriteLine("Wort: {0} = {1}x", pair.Key, pair.Value);
    }
    
    private static int SortLower(string lhv, string rhv)
    {
        return lhv.ToLower().CompareTo(rhv.ToLower());
    }
    


  • Das sieht soweit schon sehr gut aus, leider muss ich mit .add arbeiten, also das Grundgerüst sieht so aus:

    List<string> worte2 = new List<string>();
    
            worte2.Add();
            worte2.Sort();
    


  • OK, habe ich geschafft. Vielen Dank allen für die Hilfe!


Anmelden zum Antworten