博文简要信息表

项目

内容

该作业所属课程

软件工程

这个作业的要求出处

实验四 软件工程结对项目

课程学习目标

熟悉软件开发整体流程,提升自身能力

本次作业在哪个具体方面帮助我们实现目标

第一次体验一个完整的工程


点评信息

点评博客:

201671030102陈飞 词频统计软件项目报告

Github链接地址:

源码地址

点评内容:

首先,读你的博客,我觉得你对功能设计这一块的描述不够完整,比如统计完单词数量和词频后怎么显示出来?其次,运行完你的词频统计软件之后,你的代码规范,而且可以处理任意英文文本,而且我发现你的柱状图也是实现了的,但是在博客中并没有体现出来,所以我觉得你的截图还有点问题。最后,在PSP中,有三个环节的计划实际和实际时间都为0,是你没有考虑到还是什么原因呢?当然,就博客整体而言,结构完整,整个博客背景精美,值得学习。

点评心得:

在点评的过程中,我发现我们两个人之间编码风格有挺大的差异,包括在算法的实现以及功能实现的处理上,当然,针对这些差异,我们需要做的就是互相学习对方的优点,弥补自己的不足和缺点,尽自己最大的可能完善自己之前的软件,互相团结合作以更好的实现之后的软件


源码地址

源码可于此处查看,Wordfrequency文件夹中是最终的版本

结对项目实施过程

需求分析
根据实验四 软件工程结对项目所提要求,我们分析的主要需求有:
         a. 可处理任意用户输入的任意英文文本功能;
         b. 统计该文本的行数和字符数功能
         c. 指定单词词频统计功能;
         d. 前k个高频词统计功能;
         e. 统计该文本所有单词数量及词频数,并能将单词及词频数按字典顺序输出到文件result.txt功能
         f. 统计时计时功能;
         g. GUI人机交互界面;
         h. 统计文本中除冠词、代词、介词之外的高频词;

软件设计

在第二次实验中,我没有将各功能分开分别在几个类中实现,所以这一次吸取了上一次的经验教训
该软件共有10个类:
         1. frequency.java类用于调用文本输入界面MainWindows.java类
         2.MainWindows.java类用于实现文本输入界面,当输入一个文本名时如果存在,则顺利进入功能选择并实现界面OneWindows.java类,否则,弹出文件不存在的提示框;
         3. OneWindows.java类利用JFrameButton功能实现对各功能选择界面的监听,当获取到各按钮的id之后将实现各功能的界面,默认的界面是ChuLi.java类,当点击按值排序的按钮时调用GaoPin.java类,当点击查询单词的按钮时调用px.java类,当点击保存退出的按钮时将所有单词按照字母表顺序存放到result.txt文件中,将除了介词、代词、冠词以外的其余词汇按照词频从高到底的顺序保存到result1.txt文件中,之后弹出提示信息:“文件已经将除了介词、代词、冠词之外的单词按词频高低保存到result1.txt中\n将所有的单词按字典顺序保存到result.txt中\n注:此处为附加任务一所得结果”;
         4. ChuLi.java类所实现的处理信息,包括:文本名、文本行数、文本字符数、分离文本中的单词并统计各单词词频所花费的时间;
         5. px.java类用于实现输入需要输出的高频词汇的个数,点击确认后,会将按照词频从高到低的顺序输出到OneWindows.java类的界面中;
         6. GaoPin.java类用于实现从OneWindows.java类获取一个字符串,然后调用WordQuery.java类类对该字符串进行处理;
         7. wordQuery.java类用于将需要查询的特殊词对应的词频输出并且将其绘制成JFrame所实现可视化柱状图;
         8. SortMapByValue.java类根据映射的值排序,排序后可根据用户输入的k值进行输出
         9. SortMapByValue.java类根据映射的键排序,排序后将单词以及单词对应的词频保存至result.txt文件中
         10.TongJiGaoPinCi.java类用于实现除了介词、代词、冠词之外的其它词以及其对应的高频词保存至result1.txt文件中。

核心功能代码段展示

输入文本名界面,若文本不存在,则弹出提示框,否则处理文本并计时:

JButton en=new JButton("确认");
    j3.add(en);
    this.add(j1);
    this.add(j2);
    this.add(j3);
    en.addActionListener(event ->{
        Filename=FileName.getText();
        if(Filename.length()==0)
        {
            FileName.setText("文件名不能为空!");
        }
        else
        {   
            long date1=System.currentTimeMillis();
             String regex = "[1234567890”“…—‘’ /=><【】、.。,,。\"!--;:?\'\\]]";
                try {
                    // 读取要处理的文件
                    File f=new File(Filename);
                    if(!f.exists())
                    {
                        JOptionPane.showMessageDialog(null, "文件不存在", "警告", JOptionPane.ERROR_MESSAGE);
                        FileName.setText("");
                    }
                    else {
                        this.setVisible(false);
                        BufferedReader br = new BufferedReader(new FileReader(Filename));
                        
                        String value;
                        while ((value = br.readLine()) != null) {
                            hang++;
                            zifu+=value.length();
                            value = value.replaceAll(regex, " ");
                            // 使用StringTokenizer来分词
                            StringTokenizer tokenizer = new StringTokenizer(value);
                            while (tokenizer.hasMoreTokens()) {
                                String word = tokenizer.nextToken();
                                if (!hashMap.containsKey(word)) {
                                    hashMap.put(word, new Integer(1));
                                } else {
                                    int k = hashMap.get(word).intValue() + 1;
                                    hashMap.put(word, new Integer(k));
                                }
                            }
                        }
                        br.close();
                        long date2=System.currentTimeMillis();
                        time=date2-date1;
                        OneWindows o=new OneWindows();
                        o.setVisible(true);
                        o.setSize(600,300);
                        o.setLocation(300,200);
                        o.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                       
                    }

通过获取选择按钮的id,在原界面中加载实现相应功能的子界面:

ChuLi c=new ChuLi();
        this.add(c,BorderLayout.CENTER);
        c.setVisible(true);
        GaoPin g=new GaoPin();
        px p=new px();
        
        
        b1.addActionListener(event ->{
            this.add(c,BorderLayout.CENTER);
            c.setVisible(true);
            g.setVisible(false);
            p.setVisible(false);
        });
        b2.addActionListener(event ->{
            this.add(p,BorderLayout.CENTER);
            p.setVisible(true);
            g.setVisible(false);
            c.setVisible(false);
        });
        b3.addActionListener(event ->{
            this.add(g,BorderLayout.CENTER);
            g.setVisible(true);
            c.setVisible(false);
            p.setVisible(false);
        });
        b4.addActionListener(event ->{
            g.setVisible(false);
            c.setVisible(false);
            p.setVisible(false);
            TongJiGaoPinCi.tongjigaopinci();
            SortMapByKeys.sortMapByKeys();
            JOptionPane.showMessageDialog(null, "已经将全部单词按字典顺序保存reuslt.txt中\n将除了介词、代词、冠词以外的其他词按照词频高低存放到result.txt中\n", "保存", J![](https://img2018.cnblogs.com/blog/1616076/201904/1616076-20190402164039071-505842034.jpg)
OptionPane.ERROR_MESSAGE);
        ![](https://img2018.cnblogs.com/blog/1616076/201904/1616076-20190402135229436-1847344018.jpg)
    System.exit(0);
        });


程序运行

文本处理功能,文本行数、字符数统计功能,词频统计所耗费的毫秒数功能(即计时功能):
1616076-20190402135343389-1351316449.jpg

文本未找到时弹出提示框功能:
1616076-20190402135348278-1156888952.jpg

按值排序功能:
1616076-20190402135354264-1870701397.jpg

查找单词并绘制柱状图功能:
1616076-20190402135358696-98493889.png

保存并退出功能(将除了介词、代词、冠词的单词按照词频的高低顺序保存到result1.txt文件中,将所有单词按照字母表顺序保存到result.txt文件中):
1616076-20190402135409083-34503353.jpg

result.txt文件的内容:
1616076-20190402135415327-1304858333.jpg

result1.txt文件的内容:
1616076-20190402135420054-286015186.jpg


结对照片

1616076-20190402164049291-918840047.jpg
1616076-20190402164058502-1802231273.jpg


结对作业的PSP

PSP2.1

任务内容

计划共完成需要的时间(min)

实际完成需要的时间(min)

Planning

计划

10

8

Estimate

估计这个任务需要多少时间,并规划大致工作步骤

8

6

Development

开发

120

150

Analysis

需求分析 (包括学习新技术)

6

10

Design Spec

生成设计文档

15

26

Design Review

设计复审(和同事审核设计文档)

4

5

Coding Standard

代码规范(为目前的开发制定合适的规范)

5

4

Design

具体设计

10

15

Coding

具体编码

240

300

Code Review

代码复审

10

9

Test

测试(自我测试,修改代码,提交修改)

20

25

Reporting

报告

9

6

Test Report

测试报告

10

8

Size Measurement

计算工作量

2

2

Process Improvement Plan

事后总结,并提出过程改进计划

3

3

实验小结

      根据PSP表可以看到,我们在开发和编码的时候实际时间远多于计划时间,这是由于在开发和编码的过程中,JFrame图形用户界面的好多知识点已经忘了,所以在开发和编码的过程中需要不断在网上和教材上去查找和重新学习相关的知识点,所以耗费的时间比较多。
      在整个合作的过程中,刚开始我们坐在一起讨论了这次的实验需要我们做哪些工作,即用户需求是什么,接着就分工,因为我的实验二采用的算法效率优于陈飞的,所以在这次的实验中,我们是在我的第二次实验的基础上进行修改的,因为我的GUI界面实现方面的能力不好,所以就由陈飞负责GUI界面功能的设计和实现,我则负责除去介词、代词、副词后统计高频词功能、柱状图的可视化实现功能和计时功能。因为其余功能在第二次实验中已经实现了,所以其余功能就将其更加细化并完善,之后由陈飞用图形用户界面实现。
      当然,实验二中存在的处理后文本有非单词的情况和没有面向对象的思想的问题,在这次的实验中也有努力的解决。

转载于:https://www.cnblogs.com/dumanlan/p/10634397.html

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐