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

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

Github:https://github.com/fht2018/PersonProject-Java

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 450 660
• Estimate • 估计这个任务需要多少时间 450 660
Development 开发 650 970
• Analysis • 需求分析 (包括学习新技术) 30 50
• Design Spec • 生成设计文档 20 30
• Design Review • 设计复审 80 120
• Coding Standard • 代码规范 (为目前的开发制定合适的规范) 30 40
• Design • 具体设计 80 140
• Coding • 具体编码 360 460
• Code Review • 代码复审 20 30
• Test • 测试(自我测试,修改代码,提交修改) 30 200
Reporting 报告 60 70
• Test Repor • 测试报告 10 10
• Size Measurement • 计算工作量 20 20
• Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 30 40
合计 710 1040

解题思路描述

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

设计实现过程

答:核心功能就大概是字符统计,单词统计(自定义单词,至少4字母开头的字母数字组合),有效行数统计。

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

改进思路

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

代码说明

Mian类
先读取文件,实例化Count类,调用ccount(),lcount(),wcount()和wordlist()函数分别获取字符数,行数,单词数和单词字典。进行拼接输出到result.txt函数
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        //文件输入输出地址
        File fileIn = null;
        if(args.length>0){
            fileIn = new File(args[0]);
        }else {
            fileIn = new File("D:/softTest/input.txt");
            System.out.println("未输入文件名");
            System.exit(0);
        }
        //输出地址
        String out_address= "result.txt";
        FileOutputStream fileOut = new FileOutputStream(out_address);
        
        
        //实例化Count类和字符数,行数,单词数,获取单词字典的函数调用
        Count count = new Count();
        int cnum = count.ccount(fileIn);
        int lnum = count.lcount();
        int wnum = count.wcount();
        List<HashMap.Entry<String, Integer>>  wordList= count.wordlist();
        
        //将字符数,单词数,行数结果拼接
        String result = "characters:" + cnum + "\r\n" +
                        "words:" + wnum      + "\r\n" +
                        "lines:" + lnum      + "\r\n" ;

        //将单词拼接单词
        int j = 0;
        String t = new String();
        if(wordList.size()!=0){
            for(;((j<10)&&(j<wordList.size()));j++){
                t = "<"+ wordList.get(j).getKey() + ">:" + wordList.get(j).getValue();
                result += t + "\r\n";
            }
        }
        
        //输出到result.txt文件中
        fileOut.write(result.getBytes());
        fileOut.close();
    }
}
Count类
封装字符统计,行数统计,单词数统计函数和生成单词字典
import java.io.*;
import java.util.*;

public class Count {
    //初始化全局变量字符数,有效行数,单词数,单词,单词Map
    private static int cnum = 0;
    private static int lnum = 0;
    private static int wnum = 0;
    private static String word = new String();
    private static Map  ma= new HashMap();
    
    //计算字符数
    public int ccount(File fileIn){
        int len = 0;
        try{
            //读取文件
            BufferedReader bf = new BufferedReader(new FileReader(fileIn));
            //给读取的字节码变量赋个初值-1
            int byte_char  = -1;
            //判断一行是否全为空格和“\r”组成,反正行数为有效行
            Boolean flag = false;
            //开始依次读取字节码
            while ((byte_char = bf.read()) >= 0 ){
                cnum++;
                //如果非空格和“\r\n”,当前行有效行标志flag变为true
                if((byte_char != 10)&&(byte_char != 13)&&(byte_char != 32)){
                    flag = true;
                }
                //如果是空格或者“\r”
                else if ((byte_char == 10)||(byte_char == 32)){
                }
                //如果是“\n”
                else if(byte_char == 13){
                    if(flag){
                        lnum++;
                        flag = false;
                    }
                }else{
                    flag = true;
                }
                len = Count.judge(byte_char,len,ma);
            }
            //全都读取完,最后一个如果是符合要求的单词,随便输入一个非字母数字的字节码进行单词截断
            len = Count.judge(13,len,ma);
            bf.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //以“\n”+flag判断有效行数会缺少第一行
        lnum++;
        return cnum;
    }
   
    //输出全局变量行数
    public int lcount(){
        return this.lnum;
    }
   
   
    //输出全局变量单词数
    public int wcount(){
        return this.wnum;
    }
    
    //单词排序
    public List<HashMap.Entry<String, Integer>> wordlist(){
        List<HashMap.Entry<String, Integer>> wordList = WordSort();
        return wordList;
    }


    //检测单词的函数
    public static int judge(int byte_num, int len, Map m){
        if(len>=4){
            if((byte_num>=65&&byte_num<=90)){
                word = word + (char)(byte_num+32);
                len++;
            }else if((byte_num>=97&&byte_num<=122)||(byte_num>=48&&byte_num<=57)){
                word = word+ (char)(byte_num);
                len++;
            }else{
                ma = Maps(m,word);
                wnum++;
                word = new String();;
                len = 0;
            }
            return len;
        }else{
            if(byte_num>=65&&byte_num<=90){
                word = word+ (char)(byte_num+32);
                len++;
            }else if(byte_num>=97&&byte_num<=122){
                word = word+ (char)(byte_num);
                len++;
            }else{
                word = new String();;
                len = 0;
            }
            return len;
        }
    }
    
    //更新字典的函数
    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>> WordSort(){
        List<HashMap.Entry<String, Integer>> wordList = new ArrayList<HashMap.Entry<String, Integer>>(ma.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;
    }


}

单元测试

异常处理

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

项目收获

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

猜你喜欢

转载自www.cnblogs.com/fht2018/p/9634266.html
今日推荐