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/]可以找到。

 

posted @ 2020-09-19 23:52  思得  阅读(430)  评论(0编辑  收藏  举报