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:
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;
}
}
}
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;
}
}
}
