C# :: Aufgabe #156 :: Lösung #1

3 Lösungen Lösungen öffentlich
#156

Wörterzählen in Textdateien

Anfänger - C# von hollst - 23.12.2016 um 09:50 Uhr
Man schreibe ein Programm, das bei einer beliebigen Textdatei (ASCII)

a) alle Wörter und
b) alle unterschiedlichen Wörter der Längen 1, 2, 3 ... zählt, wobei zwischen Groß- und Kleinbuchstaben nicht zu unterscheiden sei.

Als Wörter-Trennzeichen sind zu verwenden:

a) alle Sonderzeichen (' ', '.', ',', tab ...) sowie Zahlen (0, 1 ... 9) und
b) alle Chars, die nicht zum Aphabet (abc...xyzäöü) gehören (damit wäre a) bereits automatisch erfüllt).

Anmerkungen:
a) Es gibt auch im Deutschen Wörter der Länge 1, z. B. in "a tempo" oder " a priori" oder bei Abkürzungen ("z. B.").
b) Als Beispieltext kann von hier die komplette Bibelausgabe nach Martin Luther 1912 als ASCII-Datei heruntergeladen und verwendet werden (ist mit 4 MB zu lang als Anhang hier, selbst als *.rar noch ca. 1.2 MB).

Viel Spaß und schöne Weihnachten sowie einen guten Rutsch und Start in 2017.
#1
5 Kommentare
2x
vote_ok
von DBqFetti (2480 Punkte) - 27.12.2016 um 22:48 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace CountWords {
  class Program {
    static string
      filename = "",
      text = "";

    readonly static char[] alphabet = GetLowerAlphabet();

    static void Main() {
      do {
        Console.Write("Datei>");
        filename = Console.ReadLine();
      } while(!File.Exists(filename));

      //Text-Datei ist nicht ASCII-Kodiert.
      //Ist auch Unsinn da ASCII keine Umlaute beinhaltet, auf welche aber explizit eingegangen werden soll.
      text = File.ReadAllText(filename, Encoding.UTF7).ToLower();

      char[] separators = text.Where(x => !alphabet.Contains(x)).Distinct().ToArray();
      string[] words = text.Split(separators, StringSplitOptions.RemoveEmptyEntries);

      Dictionary<int, int> WordLengths = CountWordLength(words);

      foreach(var WordLength in WordLengths) {
        Console.WriteLine("{0}: {1}", WordLength.Key, WordLength.Value);
      }
      Console.WriteLine("Gesamt: {0}", WordLengths.Sum(x => x.Value));

      Console.ReadKey(true);
    }

    static char[] GetLowerAlphabet() {
      List<char> AllTheLetters = new List<char>() {
        'ä', 'ö', 'ü', 
      };

      for(char letter = 'a'; letter <= 'z'; letter++) {
        AllTheLetters.Add(letter);
      }

      return AllTheLetters.ToArray();
    }

    static Dictionary<int, int> CountWordLength(IEnumerable<string> words) {
      Dictionary<int, int> AllTheLengths = new Dictionary<int, int>();

      foreach(string word in words) {
        if(!AllTheLengths.ContainsKey(word.Length)) {
          AllTheLengths.Add(word.Length, 1);
        } else {
          AllTheLengths[word.Length]++;
        }
      }

      return AllTheLengths.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value);
    }
  }
}

Kommentare:

hollst

Punkte: 13980

761 Aufgaben
132 Lösungen
117 Kommentare

#1
20.01.2017 um 22:03 Uhr
Hallo,

Gratulation, schöne kompakte Lösung. Zwei Anmerkungen bzw. Fragen:

1) der Begriff ASCII hätte in der Tat weggelassen werden in der Aufgabenstellung, Deine Anmerkung ist korrekt.

2) der Link zu der Beispieldatei lautet richtig:

http://www.sermon-online.de/search.pl?lang=de&id=6068

hat sich irgendwie ein doppeltes http dazwischengeschoben.

3) wenn ich diese Datei verwende, finde ich ein Wort mit 34 Zeichen, Du zwei. Könntest Du mir die zwei Worte, die Dein Code findet, nennen?

Gruß hollst
post_arrow
412 0

DBqFetti

Punkte: 2480


53 Lösungen
20 Kommentare

#2
21.01.2017 um 08:42 Uhr
Hallo.

Es ist zwei mal das gleiche Wort: tausendsiebenhundertfünfundsiebzig
In Exo 38:25 und Exo 38:28
Siehe auch Screenshot.
post_arrow
413 0

DBqFetti

Punkte: 2480


53 Lösungen
20 Kommentare

#3
21.01.2017 um 08:45 Uhr
Hmmm.... der Screenshot ist hier ein wenig... "klein". :D

Wenn man meinen Code am Ende z. B. um
Quellcode ausblenden C#-Code
Console.WriteLine("Länge 34: {0}", String.Join(", ", words.Where(x => x.Length == 34)));
ergänzt kann man sie sich auch schnell ausgeben lassen. Hab sie dann kurzerhand per Texteditor rausgesucht, nachdem ich wusste um welche Wörter es sich handelt.
post_arrow
414 0

hollst

Punkte: 13980

761 Aufgaben
132 Lösungen
117 Kommentare

#4
30.01.2017 um 09:04 Uhr
Ja, richtig, das 34-Char-Wort kommt 2mal vor, zu zählen ist es aber nur einmal laut b).
post_arrow
418 0

DBqFetti

Punkte: 2480


53 Lösungen
20 Kommentare

#5
02.02.2017 um 10:04 Uhr
Ahhhhh.... in der Tat. So schnell hat man nicht richtig aufgepasst.
Zeile 26 um ein .Distinct.ToArray() erweitern und es sollte richtig arbeiten.

Quellcode ausblenden C#-Code
      string[] words = text.Split(separators, StringSplitOptions.RemoveEmptyEntries).Distinct().ToArray();
post_arrow
420 0
Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben