201671010460朱艺璇 词频统计软件项目报告

  • 实验二 软件工程个人项目.

  • 实验作业要求链接实验二作业要求
  • 源码在Github的仓库主页链接地址https://github.com/jessiyx/jessiyx

  • 需求分析.
    按照《构建之法》第2章中2.3所述PSP流程,使用JAVA编程语言,独立完成一个英文文本词频统计的软件开发。
    1.程序可读入任意英文文本文件,该文件中英文词数大于等于1个。
    2.程序需要很壮健,能读取容纳英文原版《哈利波特》10万词以上的文章。
    3.指定单词词频统计功能:用户可输入从该文本中想要查找词频的一个或任意多个英文单词,运行程序的统计功能可显示对应单词在文本中出现的次数和柱状图。
    4.高频词统计功能:用户从键盘输入高频词输出的个数k,运行程序统计功能,可按文本中词频数降序显示前k个单词的词频及单词。
    5.统计该文本所有单词数量及词频数,并能将单词及词频数按字典顺序输出到文件result.txt。
    总结来说,该项目需求分析为程序可读入任意10万词以内的英文文本文件,可查找文件并可统计对应单词在文本中出现的次数和柱状图,可以根据频率出现前K个单词的词频,最后还可以将统计结果输出到result.txt


  • 功能设计.
    1.读入的英文文件放在src下,根据第二点需求以合理波特为例,讲哈利波特英文版放入src下
    2.用户输入想要查找的一个或者人一个英文单词,可出现该词在文中出现的频数和柱状图
    3.程序具有统计功能,可以按照文本中词频数降序显示词频以及单词
    4.程序可以统计整个文本字符流中的单词数并将结果输出到result.txt中,同样也放在src下

  • 设计实现.
    在设计过程中,有好几个难点,我查阅很多网上的资料和相关项目,有如下理解
    1.是读取一个文档并将其分割成单词。经过查阅资料,我选择使用BufferedReader读取文件,用列表List存储过滤后单词, 用readLine()读取流读数据,以字符串形式返回一行数据,再用split 方法 将一个字符串分割为子字符串,讲一句话中的英文单词分割出来并将其存放在Strig数组中。key值为单词,value为单词数并对单词的词频统计,用<单词:词频>这样的映射关系,Map中存放的类型key和value一个是String类型一个是int类型的,其他形式的放入Map中会提示错误。
    2.在设计排序的时候,用Map按键排序(sort by key)按键排序,将字母从a排到z对所分割的单词进行整体排序整理,如果题目要求是按照根据频数排序,即可以采用按值排序(sort by value),对整体单词根据单词频数进行排序。
    3.在讲排序结构进行输出时,可以采用getAbsoluteFile()讲结果输出到绝对路径,也就是工作路径上,也可以用getCanonicalFile()输出到当前路径,根据题目要求选择后一种输出方式,输出结果的result.txt会出现在src下。
    4.在读取文件之后,对整个文本直接进行分割成单词并计算词频,将结果输出到result.txt上。统计结果一并输出到工作台并统计完的单词总数用file.length()输出到工作台。
    5.需要手动输入的两个题目要求即某个或某几个单词的词频和前N个单词的词频用switch语句进行判断和方法调用,只列出两个问题选项,如果选择的问题不在可选范围即提示错误并重新进行选择,一个问题输出结果之后也继续进行重新选择问题。

  • 测试运行.

    • 程序开始运行.

    • result.txt中的输出结果.

    • 选择问题1.

    • 选择问题错误时.

    • 选择问题2.


  • 比较独特的或满意的代码片段.

  • 读取文件
    // 读取文件
        String filename = "src/harrypotter.txt";
        FileReader fk = new FileReader(filename);
        BufferedReader br = new BufferedReader(fk);
        // 用列表存储过滤后单词
        List<String> ls = new ArrayList<String>();
        String readLine = null;
        while ((readLine = br.readLine()) != null) {
            // 过滤出只含有字母的
            String[] correctword = readLine.split("[^a-zA-Z]");
            for (String word : correctword) {
                // 去除长度为0的行
                if (word.length() != 0) {
                    ls.add(word);
                }
            }
        


  • 用<key,value>映射,采用Map按键排序(sort by key),
    // 存储单词计数信息,key值为单词,value为单词数并对单词的词频统计
        Map<String, Integer> wordsCount = new TreeMap<String, Integer>();
        for (String li : ls) {
            if (wordsCount.get(li) != null) {
                wordsCount.put(li, wordsCount.get(li) + 1);
            } else {
                wordsCount.put(li, 1);
            }
        }
        // Map按键排序(sort by key)
        Map<String, Integer> resMap = sortMapByKey(wordsCount);
        for (Map.Entry<String, Integer> entry : resMap.entrySet()) {
            System.out.println(entry.getKey() + " " + entry.getValue());
        }
        // 格式
        // for (Map.Entry<String, String> entry : resultMap.entrySet()) {
        // System.out.println(entry.getKey() + " " + entry.getValue()); }
        //
        //


  • 讲结果输出到result.txt
File file = new File("result.txt");
        try {
            if (file.exists()) {
                file.createNewFile();
            }
            // 讲结果输出到绝对路径下
            // FileWriter ff = new FileWriter(file.getAbsoluteFile());
            // 讲结果输出到src下
            FileWriter ff = new FileWriter(file.getCanonicalFile());
            for (Entry<String, Integer> entry : resMap.entrySet()) {
                ff.write(entry.getKey() + "/" + entry.getValue() + "    " + "\n");
            }
            ff.close();
            System.out.println("统计完成");
            // System.out.println(file.getAbsoluteFile());
            // System.out.println(file.getCanonicalPath());
        } catch (IOException e) {
            e.printStackTrace();
        }

  • 总结.

    • 按照字典样式排序从a到z所用方法

      Map按键排序(sort by key), 按值排序(sort by value)。
      -- 引用自CSDN

    • 总结:
      在最后的项目结果中,我一共分成了三个java文件,一个main文件和一个Find文件和一个Valuesort文件,在main文件中实现了读取文件和按照字典顺序排序功能,在find文件中实现了查找文件并查找改词的词频和柱状图功能,在Valuesort文件中实现了查找前N个单词的词频排序。
      这个项目可能在很多人眼里都是很基础很简单的,可是我从开始到结束差不多花了五天左右,参考了很多网上的资料和别人的代码及其所用的方法。我在编程上的知识欠缺和代码基础薄弱成了做实验二的一个关键问题。
      我觉得这门课程也是真正让我意识到自己不应该无所事事,就算是从0开始还是从1开始,只要我有学习就能进步。以前的我对代码并没有热爱的感觉,导致我学了三年也只是门外汉,我自身的问题非常大。包括这个实验的代码,包括Markdown编辑器的学习,我都在努力。虽然现在很多代码和方法我暂时只能跟着别人的思路敲一遍,再去理解,但是我相信以后我会一点点慢慢变好,从现在开始真正的打基础。 可能很多人轻松就能完成的实验,我花了很多的时间,在慢慢学习java和慢慢学习Markdown编辑器的写作规范,这是用时间来提高自己的过程,我相信之后我会越来越熟练。
      做这个实验的时候,参考了很多网页,但是中间有一次电脑自动关机导致我没有保存到,所以只能列出我参考的两个网页链接。

      参考:(https://blog.csdn.net/awewong/article/details/52914804)
      (https://blog.csdn.net/qq_15807167/article/details/51902002)


  • 展示PSP.
PSP2.1 任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 10 9
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 三天 五天
Development 开发 120 130
Analysis 需求分析(包括学习新技术) 30 60
Design Spec 生成设计文档 10 9
Design Review 设计复审(和同学审核设计文档) 5 6
Coding Standard 代码规范(为目前的开发制定合适的规范) 10 15
Design 具体设计 10 10
Coding 具体编码 150 180
Test 测试(自我修改,修改代码,提交修改) 30 50
Reporting 报告 20 180
Rostmortem & Process Improvement Plan 事后总结,提出过程改进计划 3 5

GitHub上传方式: (https://blog.csdn.net/m0_37725003/article/details/80904824)

GitHub地址点击☞此处

猜你喜欢

转载自www.cnblogs.com/jessiyx/p/10506954.html