软工作业二 201621044079韩烨

1.码云项目地址

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

2.PSP表格

PSP2.1 个人开发流程 预估耗费时间(分钟) 实际耗费时间(分钟)
Planning 计划 30 30
· Estimate 明确需求和其他相关因素,估计每个阶段的时间成本 30 30
Development 开发 500 580
· Analysis 需求分析 (包括学习新技术) 50 100
· Design Spec 生成设计文档 50 50
· Design Review 设计复审 30 10
· Coding Standard 代码规范 30 10
· Design 具体设计 100 80
· Coding 具体编码 150 180
· Code Review 代码复审 30 20
· Test 测试(自我测试,修改代码,提交修改) 60 130
Reporting 报告 80 90
· 测试报告 30 30
· 计算工作量 20 20
· 并提出过程改进计划 30 40

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 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> list = new ArrayList>(wordFreq.entrySet());
        Collections.sort(list, new Comparator>() {

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

        });
        return list;
    }

6.单元测试

  • 测试文件
    软工作业二 201621044079韩烨_第1张图片

  • 测试代码
    @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();
    
    }
  • 测试截图
    软工作业二 201621044079韩烨_第2张图片

7.心得体会

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

你可能感兴趣的:(软工作业二 201621044079韩烨)