软工作业二 201621044079韩烨

1.码云项目地址

https://gitee.com/HYSOUL/PersonalProject-Java/tree/master/

2.PSP表格

PSP2.1个人开发流程预估耗费时间(分钟)实际耗费时间(分钟)
Planning计划3030
· Estimate明确需求和其他相关因素,估计每个阶段的时间成本3030
Development开发500580
· Analysis需求分析 (包括学习新技术)50100
· Design Spec生成设计文档5050
· Design Review设计复审3010
· Coding Standard代码规范3010
· Design具体设计10080
· Coding具体编码150180
· Code Review代码复审3020
· Test测试(自我测试,修改代码,提交修改)60130
Reporting报告8090
·测试报告3030
·计算工作量2020
·并提出过程改进计划3040

3.解题思路描述

题目要求如下:

  • 统计文件的字符数:
    - 只需要统计Ascii码,汉字不需考虑
    - 空格,水平制表符,换行符,均算字符
    - 统计文件的单词总数,单词:以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。
    - 英文字母:A-Za-z
    - 字母数字符号:A-Za-z0-9
    - 分割符:空格,非字母数字符号
    - 例:file123是一个单词,1file不是一个单词。fileFileFILE是同一个单词
  • 统计文件的有效行数:任何包含非空白字符的行,都需要统计。
  • 统计文件中各单词的出现次数,最终只输出频率最高的10个。频率相同的单词,优先输出字典序靠前的单词。
  • 按照字典序输出到文件result.txt:例如,windows95,windows98和windows2000同时出现时,则先输出windows2000
    • 输出的单词统一为小写格式

可以看出,其中需要主要运用到了字符串的操作,其中包括字符串的分割、字符串判断、字符串大小写的转换等等。
另外在统计词频方面还会运用到Map之类的来进行存储。
最后就是关于文件写入写出的操作的使用。


4.设计实现过程

这次的代码中主要包含了两个类:字符处理类以及文件处理类。

  1. 字符处理类
    • getCharCount():实现字符个数的统计
    • getLineCount():实现有效行数的计算
    • getWordCount():实现单词数的统计
    • getWordFreq():实现单词词频的统计
  2. 文件处理类
    • readFile():实现文件的读取操作
    • writeFile():实现文件的写入操作

5.代码说明

1.getCharCount()函数

该函数通过遍历字符进行判断,以此来达到统计字符数的效果,要注意此题中中文并不算字符,因此只要统计ascll码中的字符以及一些特殊字符即可。

    public int getCharCount() // 统计文件字符数
    {
        char c;
        int i = 0;
        while (i < text.length()) {
            c = text.charAt(i);
            if (c >= 32 && c <= 126 || c == '\r' || c == '\n' || c == '\t') {
                charNum++;
            }
            i++;
        }
        return charNum;
    }

 
2.getWordCount()函数

该函数用于判断单词的个数,先根据空白字符来进行分词操作,然后再根据单词的要求,即长度,格式等规定,进行判断,然后返回总数。。

    public int getWordCount() // 统计单词总数
    {
        String t = text;
        String[] spWord = t.split("\\s"); // 分词
        for (int i = 0; i < spWord.length; i++) {
            if (spWord[i].length() < 4) { // 判断长度是否大于等于4
                continue;
            } else {
                int flag = 1; // 判断字符串的前四位是否是英文字母
                char c;
                for (int j = 0; j < 4; j++) {
                    c = spWord[i].charAt(j);
                    if (!(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z')) {
                        flag = 0;
                    }
                }
                if (flag == 1) {
                    wordCount++;
                }
            }
        }
        return wordCount;
    }
3.getLineCount()函数

该函数用于统计有效行数,先将每一行进行分割,然后存入字符数组,然后遍历数组,判断字符串去掉空格之后的长度是否为0,如果为0即为无效行数。最后返回有效行数的个数。

 public int getLineCount() { // 统计有效行数

     String[] line = text.split("\r\n"); // 将每一行分开放入一个字符串数组
     for (int i = 0; i < line.length; i++) { // 找出无效行,统计有效行

         if (line[i].trim().length() == 0)
             continue;
         ValidLine = ValidLine + 1;
     }
     return ValidLine;
 }
4.getWordFreq()函数

该函数用于单词词频的统计,先按照单词的判断方法进行判断一个词是否是单词,然后使用一个Map进行存储,具体方法为先判断Map中之前是否存过该数据,若没有存过,则将其存入并置value值为1,若存过,则将该值的value值加1。最后将即可map根据要求进行排序即可

    public List getWordFreq() { // 对单词词频的Map进行排序

        wordFreq = new HashMap<String, Integer>();
        String t = text;

        String[] spWord = t.split("\\s"); // 分词
        for (int i = 0; i < spWord.length; i++) {
            if (spWord[i].length() < 4) {
                continue;
            } else {

                int flag = 1;
                char c;

                for (int j = 0; j < 4; j++) {
                    c = spWord[i].charAt(j);

                    if (!(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z')) {
                        flag = 0;
                    }
                }
                if (flag == 1) {
                    spWord[i] = spWord[i].trim().toLowerCase();
                    if (wordFreq.get(spWord[i]) == null) {
                        wordFreq.put(spWord[i], 1);
                    } else
                        wordFreq.put(spWord[i], wordFreq.get(spWord[i]) + 1);

                }
            }
        }

        List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(wordFreq.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {

            @Override
            public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { // 对Map中内容进行排序,先按词频后按字典顺序
                if (o1.getValue() == o2.getValue()) {
                    return o1.getKey().compareTo(o2.getKey());
                }
                return o2.getValue() - o1.getValue();
            }

        });
        return list;
    }

6.单元测试

  • 测试文件
    1238113-20180918181914172-1258384712.png

  • 测试代码
    @Test
    public void testGetCharCount() throws IOException {//统计字符数量测试
        FileDeal fd = new FileDeal();
        String text1 = fd.FileToString("text/text1.txt");   
    
        WordDeal wd1 = new WordDeal(text1);
    
        int cn1 = wd1.getCharCount();
    
    }
    @Test
    public void testGetWordCount() throws IOException {//统计单词数量测试
        FileDeal fd = new FileDeal();
        String text1 = fd.FileToString("text/text1.txt");
        WordDeal wd1 = new WordDeal(text1);
        int wn1 = wd1.getWordCount();
        
    }
    @Test
    public void testGetWordFreq() throws IOException {//统计词频测试
        
        FileDeal fd = new FileDeal();
        String text1 = fd.FileToString("text/text1.txt");
        WordDeal wd1 = new WordDeal(text1);
        List wf1 = wd1.getWordFreq();
        
    }

    @Test
    public void testGetLineCount() throws IOException {//统计有效行数测试
        FileDeal fd = new FileDeal();
        String text1 = fd.FileToString("text/text1.txt");
        WordDeal wd1 = new WordDeal(text1);
        int wn1 = wd1.getLineCount();
    
    }
  • 测试截图
    1238113-20180918182042413-282533856.png

7.心得体会

这次的实验最难的地方还是每一步的规范,以前写代码的时候并不会注意到那么多,所以在规范上花的时间还蛮多的。然后就是在写代码的时候忘记了很多Java的语法,特别是词频统计的函数,用到了比较器之类的,也是花了很多时间。然后在异常处理方面考虑还是不够多,下次会注意这方面的内容。

转载于:https://www.cnblogs.com/HYSOUL/p/9664682.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值