福大软工1816 · 第二次作业-个人项目

Part 1.卷首语

github传送门

本次的开发环境
  • Windows 10 64bit + Eclipse + JProfiler

    Part 2.PSP表格

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划------
· Estimate· 估计这个任务需要多少时间1020
Development开发
· Analysis· 需求分析 (包括学习新技术)120150
· Design Spec· 生成设计文档2030
· Design Review· 设计复审1020
· Coding Standard· 代码规范 (为目前的开发制定合适的规范)2020
· Design· 具体设计6040
· Coding· 具体编码7001320
· Code Review· 代码复审3030
· Test· 测试(自我测试,修改代码,提交修改)3060
Reporting报告
· Test Repor· 测试报告4060
· Size Measurement· 计算工作量2020
· Postmortem & Process Improvement Plan· 事后总结, 并提出过程改进计划2060
合计10801830

Part 3.解题思路

首先问题的大致要求是需要统计文本中的各参数数量与词频,整体的先后思路如下:

  • 1.首先要做的事情就是将.txt中的文本转换为可操作的字符串(结果还需要写入.txt文件中),这个过程关系到文件流操作;
  • 2.对于可操作的字符串,要对其进行筛选、转化、切割、选择(开头4个字母后含若干个字母数字的形式);
  • 3.对于处理后的单词集,需要对其进行词频统计,并在统计结束后排序好先后顺序传回主函数,基本任务完成。

Part 4.实现过程

  • countChar:负责字符数的统计;
  • countVec:负责单词数的统计;
  • countLine:负责行数的统计;
  • createMap:负责处理HashMap词频表的建立
    1093071-20180912223051981-1711813190.jpg

Part5.关键代码展示

简单的列出主要花费自己心思去写的两部分代码,其余的详细请见github上的源码。
对于单词的选择,我主要利用的是正则匹配的方式来选择,先将内部不符合的元素用某一符号代替,而这一符号将作为下一次分隔符标志,利用Pattern和Matcher去除非英文数字字符,而后进一步对单词的样式进行约束,对于符合正则表达式的单词加入列表中提供给后续使用

public static int countwords(int count,String text){
        list.clear();   //做初始化清空字符集处理
        String regex ="[^0-9a-zA-Z]";   //剔除文本中的非字母和数字的部分并以!作为暂时的分隔符
        Pattern pat = Pattern.compile(regex);
        Matcher mat = pat.matcher(text);
        text = mat.replaceAll("!");             
        String [] textArray = text.split("!+");     //按照分隔符划分
        String v_regex = "^[a-z]{4}[a-z0-9]*$";     //对单词形式进行约定
        for(String i:textArray){
            Pattern v_pat = Pattern.compile(v_regex);
            Matcher v_mat = v_pat.matcher(i);
            if(v_mat.matches())
                list.add(i);
        }
        return list.size();
    }

对于词频分类和统计,这里利用了HashMap,简单且易查找,<Key,Value>的形式很好的记录了<单词本身,出现次数>这样的记录。最后将记录好的Map进行排序,按照题给要求,先以Value值做参考,在Value值相同的情况下,以Key值优先为准。

public static List<Map.Entry<String,Integer>> createHashMap(List<String>list){
        Map<String,Integer> ver = new HashMap<String, Integer>();
        for(String i:list){
            if(!ver.containsKey(i))
                ver.put(i, 1);
            else{
                Integer num = ver.get(i);
                ver.put(i, num+1);
            }
        }
        List<Map.Entry<String,Integer>> verlist = new ArrayList<Map.Entry<String,Integer>>(ver.entrySet());
        Collections.sort(verlist,new Comparator<Map.Entry<String, Integer>>(){
            public int compare(Map.Entry<String, Integer> o1,Map.Entry<String, Integer> o2) {
                if(o1.getValue()==o2.getValue()){
                    return (o1.getKey()).compareTo(o2.getKey());
                }
                return o2.getValue()-o1.getValue();
            }
        });
        return verlist;
    }

下面主要是我对于IO操作的异常进行处理的基本形式

public static int countChar(String path,int count) throws IOException{
        try {
            ...
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally{
            ...
        }
        return count;
    }

Part6.性能分析

1093071-20180912215613679-1629385170.png

1093071-20180912215621005-1168034537.png

以下主要是调用各个不同类中的接口,所以Main中的覆盖率会为0,整体的情况符合正常的操作结果。
1093071-20180912215631911-835196346.png

1093071-20180912215638900-108131834.png

进行单元测试的过程中,可通过如下的报错来寻找自己的疏漏之处,每一环节都能够很好的定位到。
1093071-20180912215716654-493577032.png

Part7.感想

有了初步的构思以后,边学习边敲java代码,实践中去逐步的完善自己,总体来说,我对自己的表现还是挺满意的。过程中接触了单元测试,找到了自己许多原先疏漏的小细节,在逐步改进之下完善着自己的代码。怎么说呢,可能还是自己的慢性子的原因,每天都在投入时间去边敲边改,但是很遗憾,得出最终成果的时间还是压到了接近与deadline之前一些些,所以我对自己下一次任务的期望是自己能够有更高的效率,达到更好的效果,以上。
1093071-20180912223958982-1929177895.png

也希望大家能够对我提出宝贵的意见,谢谢大家,小废的程序员之路道阻且长......

Part8.后记

后续在完成作业以后,看到了许多同学都有意识的去讨论测试数据的大小问题,所以自己也做了一下大型文本的测试,果然发现出错。总结一下自己得出的结论:String对于连接操作(“+”)效率很低,因此导致了我程序一直没办法正常运行,后改用StringBuilder,利用.append()方法来进行文本的逐行拼接,成功解决了上述所困扰我的问题。(更新代码内容详见github源码部分),后续将会对为什么String效率低的问题分析好后作出解释,暂告一段落,谢谢(附上大型数据测试情况)
这里简单的结合office word自带的字数统计功能校验如下:
1093071-20180917095530392-31783538.png

转载于:https://www.cnblogs.com/S031602219/p/9637645.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值