C# :: Aufgabe #156
3 Lösungen
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.
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.
Lösungen:
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); } } }
Program.cs
C#-Code
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; using Word = Microsoft.Office.Interop.Word; namespace ConsoleCountWords { static class Program { const string allChars = "abcdefghijklmnopqrstuvwxyzäöüß"; [STAThread] static void Main(string[] args) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "Textdateien (*.txt)|*.txt"; if (ofd.ShowDialog() == DialogResult.OK) { string file = ofd.FileName; string text = File.ReadAllText(file, Encoding.ASCII); object missing = System.Reflection.Missing.Value; Word.Application app = new Word.Application(); Word.Document document = app.Documents.Add(ref missing, ref missing, ref missing, ref missing); document.Content.SetRange(0, 0); document.Content.Text = text; Dictionary<int, int> wordLength; int count = document.CountWords(out wordLength); if (count == 1) { Console.WriteLine("1 Wort gezählt"); } else { Console.WriteLine("{0} Wörter gezählt", count); } foreach (var item in wordLength.OrderBy(a => a.Key)) { if (item.Value == 1) { Console.WriteLine("1 Wort der Länge {0} gezählt", item.Key); } else { Console.WriteLine("{0} Wörter der Länge {1} gezählt", item.Value, item.Key); } } document.Close(Word.WdSaveOptions.wdDoNotSaveChanges); app.Quit(); Console.ReadLine(); } } static int CountWords(this Word.Document doc, out Dictionary<int, int> wordLength) { int c = 0; wordLength = new Dictionary<int, int>(); for (int i = 1; i <= doc.Words.Count; i++) { string word = doc.Words[i].Text.ToLower(); if (!allChars.Contains(word.Last())) { word = word.Substring(0, word.Length - 1); } if (word.All(a => allChars.Contains(a)) && word.Length > 0) { c++; if (wordLength.ContainsKey(word.Length)) { wordLength[word.Length]++; } else { wordLength.Add(word.Length, 1); } } } return c; } } }
C#-Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ascii { class Program { public static void Main() { char[] all_ok = "abcdefghijklmnopqrstuvwxyzäöüABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜß".ToCharArray(); char[] trenner = " .!?,;<>()[]{}§$%&=+-*/:#|_~\"\'@".ToCharArray(); string path = "Bibelausgabe_Martin_Luther_1912_als_ASCII_Datei.txt"; Console.WriteLine("source: " + path + Environment.NewLine); int counter_lines = 0, counter_words = 0, counter_words_ok = 0; Dictionary<String, Int32> dictionary = new Dictionary<string, int>(); int max_wortlaenge = 0; string line; System.IO.StreamReader file = new System.IO.StreamReader(path, Encoding.Default); while ((line = file.ReadLine()) != null) { String[] words_in_line = line.Split(trenner, StringSplitOptions.RemoveEmptyEntries); counter_words += words_in_line.Length; for (var i = 0; i < words_in_line.Length; i++ ) { char[] wordchars = words_in_line[i].ToCharArray(); Boolean bo_ok = true; for(var j = 0; j < wordchars.Length; j++) if (!(all_ok.Contains(wordchars[j]))) bo_ok = false; if (bo_ok) { counter_words_ok++; String erg = words_in_line[i].ToLower(); if (erg.Length > max_wortlaenge) max_wortlaenge = erg.Length; if (dictionary.ContainsKey(erg)) { int value = dictionary[erg]; value++; dictionary[erg] = value; } else dictionary.Add(erg, 1); } } counter_lines++; } file.Close(); Console.WriteLine("there were {0:n0} lines, {1:n0} words and {2:n0} words_ok", counter_lines, counter_words, counter_words_ok); Console.WriteLine(); Console.WriteLine("different words: " + dictionary.Count.ToString() + ", longest word has " + max_wortlaenge.ToString() + " chars"); Console.WriteLine(); int[] verteilung = new int[max_wortlaenge]; foreach(String s in dictionary.Keys) verteilung[s.Length - 1] += 1; Console.WriteLine("distribution" + Environment.NewLine); Console.WriteLine(verteilung.ToMyString()); Console.WriteLine("ready"); Console.ReadKey(); } } static class myExtensions { public static string ToMyString(this int[] b) { String erg = String.Empty; for (var i = 0; i < b.Length; i++) erg += (i + 1).ToString("00") + ": " + b[i].ToString() + Environment.NewLine; return erg; } } }