软工实践第二次作业-词频统计

软工实践第二次作业-词频统计

题目地址:https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1816W/homework/2085
Github:https://github.com/fht2018/PersonProject-Java2

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

解题思路描述

答:一看到题目使用c++或者java,一下就选择最近在学习的java。大概浏览了一下要求,打算先设计核心功能之后再实现细节比如命令行,分装函数什么的。大概就是读取文本信息,依次判断字节码范围判断字符数,以“\n”为行首判断行数在加上第一行,同时依次判断是否是单词,并有一个函数来处理字典。

设计实现过程

答:核心功能就大概是字符统计,单词统计(自定义单词,至少4字母开头的字母数字组合),有效行数统计。
所以先获取数据,到网上查了一下java字符流读取文件,读取到数据后就开始处理,通过一个一个字符的遍历,判断字符的字节码在0到127的,超过的忽略(忽略汉字及其他字符)。定义一个word的全局变量存放单词,和一个全局变量len存单词的长度,写一个judge函数把字符依次送入判断,如果符合单词的要求,把获得的单词送入一个更新字典的函数。最后把数据拼接在一起,输出到result.txt。进行简单测试之后,将核心功能函数分装到Count类中。

改进思路

答:在for循环中,第一个参数变量i,定义int i在循环外面比循环里面性能稍微好一些,避免每次循环都进行定义一个i。还有就是读取数据最开始是用字节流读取,字节流是直接对数据本身读取操作。后面该用字符流,字符流是先进行缓存在进行处理。由于是一个一个字节的读取,字节流会频繁的对文件进行操作,而字符流是就能减少一部分开销。

代码说明

定义一个Count类,在里面依次封装字符统计,有效行数统计,单词统计等函数。在构造函数中读取文件里的信息
    //构造函数
    public Count(File fileIn) {
        try{
            //读取文件,注意要以utf8格式读取,不然cmd编译和编译器编译出来的读取字符数会有偏差
            BufferedReader bf = new BufferedReader(new InputStreamReader(new FileInputStream(fileIn),"utf8"));
            
            //用StringBuffer依次存每个字符
            StringBuffer contents = new StringBuffer();
            int byte_char = -1;
            //开始依次读取字节码
            while ((byte_char = bf.read()) >= 0) {
                contents.append((char)byte_char);
            }
            content = contents.toString();
            bf.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    //字符统计函数,先把"\r\n"全部替换成"\n",防止回车在不同的编码环境下被统计为2个字符
    public int charactersCount(){
        String clearcontent = content.replaceAll("\r\n","\n");
        int charactersnum = clearcontent.length();
        return charactersnum;
    }
    
    //有效行数统计函数,以"\n"判断行数,设置flag判断是否为空字符
    public int lineCount(){
        Boolean flag = false;
        int linenum = 0;
        int i = 0;
        for (;i<content.length();i++){
            if(content.charAt(i) != '\r' && content.charAt(i) != '\n' && content .charAt(i) != ' ' ){
                flag = true;
            }else if(content.charAt(i) == '\n'){
                if(flag){
                    linenum++;
                    flag = false;
                }
            }
        }
        if(flag){
            linenum++;
        }
        return linenum;
    }
    
    //单词统计函数,将大写字母转为小写字母,再将所有非字母数字的字符替换为“|”,通过“|”切割单词,在判断单词是否符合四个字母开头的要求,符合的话存进字典
    public int wordCount(){
        int wordNum = 0;
        String regex = "[^0-9A-Za-z]";
        String contentString  = content.toLowerCase().replaceAll(regex,"|");
        String[] contents = contentString.split("\\|");
        int i = 0;
        for (; i <contents.length ; i++ ) {
            if(contents[i].length()>=4){
                if(Character.isLetter(contents[i].charAt(0))){
                    if(Character.isLetter(contents[i].charAt(1))){
                        if(Character.isLetter(contents[i].charAt(2))){
                            if(Character.isLetter(contents[i].charAt(3))){
                                wordNum++;
                                Maps(ma,contents[i]);
                            }
                        }
                    }

                }
            }
        }
        if(!ma.isEmpty()){
            words = Sort(ma);
        }
        return wordNum;
    }

    //更新字典的函数,将符合的单词存进全局静态变量字典中
    public static Map Maps(Map m, String s){
        if(m.containsKey(s)){
            int n = (int)m.get(s);
            n++;
            m.put(s,n);
        }else{
            m.put(s,1);
        }
        return m;
    }

    //单词排序函数,将字典依次按照出现次数排序,次数相同的按字典序排序
    public static List<HashMap.Entry<String, Integer>> Sort(Map m){
        List<HashMap.Entry<String, Integer>> wordList = new ArrayList<HashMap.Entry<String, Integer>>(m.entrySet());

        Comparator<Map.Entry<String, Integer>> com = new Comparator<Map.Entry<String, Integer>>(){

            @Override
            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();//从大到小
            }
        };
        wordList.sort(com);
        return wordList;
    }

单元测试

1479159-20180912200917693-1370491165.png

异常处理

1.FileNotFoundException 文件无法找到的时候抛出错误
2.IOException 读取文件失败的时候抛出错误
3.判断args[0] 如果没有输入文件名,终止程序,抛出错误

项目收获

答:之前的两年对文件的处理非常少,就仅有一两次用php对文件进行上传下载处理,大部分都是进行数据的处理,对文本的处理是一次也没试过。再加上刚学的java,处处都是新知识,不过最后能成功打出代码也是不错的一件事。java功能确实十分强大,有一套很全的类库。要学的东西确实还有非常多,

转载于:https://www.cnblogs.com/fht2018/p/9634266.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值