201671030122杨凡亿 实验二 词频统计软件项目报告

项目 内容
课程名称 2016级计算机科学与工程学院软件工程(西北师范大学)
作业要求 实验三 软件工程个人项目
作业目的 1.掌握软件项目个人开发流程
2.掌握Github上发布软件项目的操作方法


一.需求分析

  • 程序可读入任意英文文本文件,即用户需要自己输入文件名。
  • 程序需要很壮健,能读取容纳英文原版《哈利波特》10万词以上的文章,即数据的存储方式。
  • 指定单词词频统计功能,即(1)用户可输入一个或多个单词查询对应的词频(2)并显示对应的柱状图。
  • 高频词统计功能:用户从键盘输入高频词输出的个数k,运行程序统计功能,可按文本中词频数降序显示前k个单词的词频及单词。
  • 统计该文本所有单词数量及词频数,并能将单词及词频数按字典顺序输出到文件result.txt。


二.功能设计

  • 菜单功能。列出用户可以操作的命令。对于用户输入的无效命令应该有相应的错误处理能力。
  • 文件的输入和输出功能。在文件输入时,若文件不存,则应有相应的错误处理功能。
  • 词频统计功能。
  • 排序功能。按值排序,按键排序。
  • 显示功能。(1)显示指定单词的词频和柱状图,若用户输入无效单词,应该有相应提示。(2)高频词的统计功能。


三.设计实现

(1)程序共有两个类。

  • Main.java是主类。主要利用switch结构对用户输入的命令进行判断,并调用相应的函数。
  • function.java 主要是一些功能方法。包括:文件的读入(input)、菜单显示(menu)、指定单词词频统计(frequency)、排序(rank)、高频词统计(Highwordcount)、输出到文件result.txt(output)
  • 程序执行时,主要是在主类Main.java里面调用function.java类里面的方法,实现需要的功能。

(2)数据结构:用HashMap<String, Integer>存储分词后的单词和对应的词频。
(3)总体流程图


四.测试运行

  • 文件的读入

  • 高频词统计

  • 指定单词词频统计

  • 输入到result.txt

  • 一些错误处理


五.部分代码

  • 文件读入并统计词频

try {
     FileInputStream fis = new FileInputStream(filename);
     BufferedReader br = new BufferedReader(new InputStreamReader(fis));
     String temp="";
     String info="";
     while((temp = br.readLine())!=null)
     {
         String[] str = temp.split("([^a-zA-Z])"); //过滤出只含有字母的
         for(int i=0;i<str.length;i++)
         {
             String word = str[i].trim();
             if(word.length()!=0)    //去除长度为0的行
             staff.put(word, staff.getOrDefault(word, 0)+1);
         }
     }
     br.close();
     rank();//按值排序
     System.out.println("文件读入成功!请继续...");
   }catch(Exception e) {
     System.out.println("文件不存在!!!请重新确认!");
    }
  • 文件输出到result.txt

 Set<Entry<String,Integer>> mapEntries = staff.entrySet();//该方法将键和值的映射关系作为对象存储到了Set集合中
      
      List<Entry<String,Integer>> aList1 = new ArrayList<Entry<String,Integer>>(mapEntries);
      //按字典序排序
      Collections.sort(aList1, new Comparator<Entry<String,Integer>>() {
           
          @Override
          public int compare(Entry<String, Integer> ele1,
                  Entry<String, Integer> ele2) {

              return ele1.getKey().compareTo(ele2.getKey());
          }
      });

      PrintWriter out = null;
      try {
          out = new PrintWriter("result.txt");
          out.println("total: "+aList.size()); //输出总词数
          for(Entry<String,Integer> entry: aList1) 
          {
              out.println(entry.getKey()+"\t"+entry.getValue());
          }
      } catch (FileNotFoundException e1) 
      {
          // TODO Auto-generated catch block
          e1.printStackTrace();
      }
      out.close();
      System.out.println("已写到result.txt  请继续...");
  }


六.总结

  • 每个功能的实现都在function类中,在主类里面通过类名直接调用相应的方法实现功能,以此实现模块化。
  • 在画柱状图时,本想采用重写paint()方法来实现,也参考了网上的一些代码,但由于自己知识有限,没能实现。后面会继续完善。
  • 对于需求分析和设计,应当重视。在此次设计中,由于没有做好这些,在编码完成测试时才发现一些功能和需求不同,又花了一点时间修改。这要是在大项目中有点不可想象。


七.PSP

PSP 任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 8 5
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 8 5
Development 开发 170 220
Analysis 需求分析(包括学习新技术) 20 15
Design Spec 生成设计文档 10 12
Design Review 设计复审 11 13
Coding Standard 代码规范(为目前的开发制定合适的规范) 5 9
Design 具体设计 10 12
Coding 具体编码 70 130
Code Review 代码复审 10 15
Test 测试(自我测试,修改代码,提交修改) 30 60
Reporting 报告 15 20
Test Report 测试报告 6 9
Size Measurement 计算工作量 5 3
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 5 4
  • 从表中可以看到,在编码和测试部分花费了很长是的时间,和预期的是计划差距有点大。主要是对于需求没有弄得很清楚,导致在测试阶段根据测试结果又修改代码,浪费了很时间;其次是很久没有用到java,在编码时又化了很多时间看书。我之前一直对需求分析和设计不是很重视,但通过这次小项目,我想对于需求分析和设计等有了更深的体会和感受,在接下来的学习中,会按照软件开发流程完成学习任务。

点击此处查看源码GitHub

猜你喜欢

转载自www.cnblogs.com/yangfy2019/p/10561128.html