20200917-2 词频统计 已更新附加题!
此作业的要求参见[https://edu.cnblogs.com/campus/nenu/2020Fall/homework/11206]
codding项目地址https://e.coding.net/thinkget/wf/wf.git(https://thinkget.coding.net/public/wf/wf/git/files)
GitHub地址 https://github.com/chxin579/words.git
词频统计 SPEC
功能实现
首先要写一个词频统计功能,方便进行多次调用,词频统计功能关键点主要是去除多余字符,将单词改为小写,使用合适的数据结构(这里使用hashtable)统计和排序。
hashtable 一个哈希表,可以快速进行插入查找删除操作,但是不能进行排序,需要改成普通数组排序。
public static void CountWords(string text)//统计单词功能 { text = text.ToLower();//大写换成小写 text = Regex.Replace(text, "[!@#$%^&*()`,./;:\"<>`?...“”]", " ");//替换标点 text = text.Replace("\n", " ");//替换换行符 text = Regex.Replace(text, "[\\s+]", " ");//替换多余空格 string[] textsp = text.Split(' '); Hashtable ht = new Hashtable(); //Hashtable for (int i = 0; i < textsp.Length; i++) { if (textsp[i] == "") continue;//过滤空字符 if (ht.ContainsKey(textsp[i])) { ht[textsp[i]] = (int)ht[textsp[i]] + 1; } else { ht.Add(textsp[i], 1); } } OutputInfo(ht); } public static void OutputInfo(Hashtable ht)//输出信息 { string[] arrKey = new string[ht.Count];//存放hashtable中的键名 int[] arrValue = new int[ht.Count];//存放hashtable中的值 ht.Keys.CopyTo(arrKey, 0); ht.Values.CopyTo(arrValue, 0); Array.Sort(arrValue, arrKey);//对其数组进行排序 Console.WriteLine("total " + ht.Count + "\n"); int num = ht.Count - 11; if (ht.Count - 11 < 0) num = 0; for (int j = ht.Count - 1; j >= ht.Count - 11; j--) { Console.WriteLine("" + arrKey[j] + "\t" + arrValue[j]); } }
其次写出根据题目要求写出分流操作 功能关键点:读取命令行参数,读取文件内容。
static void Main(string[] args) { if (args.Length == 0)//自定义写入模式 { WriteText(); } else { if (args.Length == 1 && args[0] == "-s")//控制台重定向输入模式 { ReadConsoleInput(); } else if (args.Length > 1 && args[0] == "-s")//自定义文件模式 { for (int i = 1; i < args.Length; i++) { string s = System.IO.File.ReadAllText(args[i]); CountWords(s); } } else if (args.Length == 1 && args[0] != "-s")//已有文件查找模式 { DirectoryInfo directory = new DirectoryInfo(args[0]); if (directory.Exists) { ScanDir(args[0]); } else { if (File.Exists(args[0])) { string s = System.IO.File.ReadAllText(args[0]); CountWords(s); } else if (File.Exists(args[0] + ".txt")) { string s = System.IO.File.ReadAllText(args[0] + ".txt"); CountWords(s); } else ScanFile(args[0]); } } } }
最后补全各个功能。功能关键点:遍历目录列表,文件名查找,控制台输入,重定向输入。
public static void ScanDir(string dir)//扫描目录 { DirectoryInfo directory = new DirectoryInfo(dir); foreach (FileInfo file in directory.GetFiles()) { string s = System.IO.File.ReadAllText(file.FullName); CountWords(s); } } public static void ScanFile(string file)//搜索文件 { DirectoryInfo[] dateDirArr = new DirectoryInfo(".").GetDirectories(); foreach (DirectoryInfo directoryInfo in dateDirArr) { string fullName = directoryInfo.Name + "\\" + file + ".txt"; string fullName1 = directoryInfo.Name + "\\" + file; if (File.Exists(fullName)) { string s = System.IO.File.ReadAllText(fullName); CountWords(s); break; } else if (File.Exists(fullName1)) { string s = System.IO.File.ReadAllText(fullName1); CountWords(s); break; } else continue; } } public static void WriteText()//文本输入模式 { string text = Console.ReadLine(); CountWords(text); } public static void ReadConsoleInput()//标准输入模式 { int a = Console.Read(); string word = ""; Hashtable ht = new Hashtable(); while (a > -1) { if ((a >= 65 && a <= 90) || (a >= 96 && a <= 122) || a == 39 || a == 45) { if (a >= 65 && a <= 90) a = a + 32; word = word + ((char)a).ToString(); } else { if (word != "") { if (ht.ContainsKey(word)) { ht[word] = (int)ht[word] + 1; } else { ht.Add(word, 1); } } word = ""; } a = Console.Read(); } OutputInfo(ht); }
功能演示
功能1 小文件输入。
功能2 支持命令行输入英文作品的文件名,请老五亲自录入。
功能3 支持命令行输入存储有英文作品文件的目录名,批量统计。
功能4 从控制台读入英文单篇作品,
遇到的一些问题:
作业中给的测试实例中统计是不准确的。比如下面这个例子
you: you? you! you you you
测试例子中会出现多个英文单词,最后导致统计数量偏少,应该加强特殊字符过滤。现在我的程序已经修复可以正常统计。
附加题
统计5字母单词出现次数最多的十个 格式 wf -n 单词字母数量 -t 显示出现的单词数量 -s 文件
统计6字母单词出现次数最多的二十个
统计6字母单词出现次数最多的一百个
关键点:自定义入口,判断字符串数量
自定义入口功能
int n = 0; int t = 0; string file = ""; for (int i = 0; i < args.Length; i++) { if (args.Length % 2 != 0) { Console.WriteLine("error"); return; } if (args[i] == "-n") { n = Convert.ToInt32(args[i + 1]); i++; } if (args[i] == "-t") { t = Convert.ToInt32(args[i + 1]); i++; } if (args[i] == "-s") { file = args[i + 1]; i++; } } if (t == 0) t = 10; if (n > 0 && t > 0 && file != "") { string s = System.IO.File.ReadAllText(file); CountWordsCustomize(s, t, n); } else { Console.WriteLine("error"); }
判断字符串数量加一句s.Length==ennum就可以了
PSP
(8分)
(5分。虽然只有5分,但此题如果做错,因为教师得不到你的代码,所以会导致“功能实现”为负分。)
代码要求在 coding.net 做版本控制。要求push&pull时使用git客户端,不允许使用web页面
项目地址https://e.coding.net/thinkget/wf/wf.git(https://thinkget.coding.net/public/wf/wf/git/files)
测试
“从控制台读入英文单篇作品”中的英文作品,包括不限于[https://github.com/weijunying2019102969/novelsfortest.git]中的测试用例。大量英文原版(无版权,不是盗版)的测试用例在[http://www.gutenberg.org/]可以找到。