第一次作业

要求0:https://edu.cnblogs.com/campus/nenu/2016CS/homework/2110

要求一:

  地址:https://git.coding.net/yu_mai/wf.git   我使用的Java语言,由于打包过程出现问题,没有生成可执行文件。我会在后面补交仓库地址,希望见谅。

要求2(10分)

SP2.1

任务内容

计划共完成需要的时间(min)

实际完成需要的时间(min)

Planning

计划

60

70

Estimate

估计这个任务需要多少时间,并规划大致工作步骤

40

50

Development

开发

300

450

Analysis

需求分析 (包括学习新技术)

100

130

Design

具体设计

90

90

Coding

具体编码

480

600

Code Review

代码复审

40

60

Test

 测试(自我测试,修改代码,提交修改)

90

120

Reporting

报告

180

210

Size Measurement

计算工作量

40

40

Postmortem & Process Improvement Plan

事后总结, 提出过程改进计划

40

50

功能模块

预计时间(min)

实际时间(min)

功能1

One day

150

功能2

One day

140

功能3

One day

100

测试功能

30

60

要求3(20分)

  思考过程:在最初看到这个题目时,我当时觉得难度很大,因为我本人的代码量较少,写代码经验少,故而对题目有些抵触,它不仅要求多还有不同的功能,我觉得自己的能力够不到。后来和同学交流这个题目时,她们帮我梳理这个题目的思路,她们告诉我3个功能可以单独思考,第一个功能是普通的词频统计,可以去网上找找相关的资料;第二个功能是在普通的词频统计的基础上进行字典排序;最后一个功能对第二个的结果排序,按升序的方式排列。最大的难度是从文件路径中获取文件内容,这一点上要明确文件存储地址。参考的代码地址:http://www.cnblogs.com/guozhe/p/5975505.html。(主要功能)

主要代码:用Java 编写,分为两个类CountWord 与 UseCountWord

<1>、CountWord类中包括功能一,功能二,功能三,等主要类,如下

功能一:CountFile()  基本的词频统计

public void CountFile(){
        // 用HashMap存放<单词:词频>这样一个映射关系
        HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
        // 用正则表达式来过滤字符串中的所有标点符号,以及数字
        String regex = "[^a-zA-Z0-9]|\ ";
        try {
            // 读取要处理的文件
            FileInputStream inputStream = new FileInputStream(new File(path));
            BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream));
            while ((value = buffer.readLine()) != null) {
            String str = value.toString().toLowerCase();
                str = str.replaceAll(regex, " ");
                // 使用StringTokenizer来分割词
                StringTokenizer tokenizer = new StringTokenizer(str);
                while (tokenizer.hasMoreTokens()) {
                    String word = tokenizer.nextToken();
                    if (isLegal(word)){
                        //判断是否合法
                    if (!hashMap.containsKey(word)) {
                        hashMap.put(word, new Integer(1));
                    } else {
                        int k = hashMap.get(word).intValue() + 1;
                        hashMap.put(word, new Integer(k));
                    }
                    }
                    }
                }
            
            //输出结果
            List<Map.Entry<String, Integer>> list =
                    new ArrayList<Map.Entry<String,Integer>>(hashMap.entrySet());
            System.out.println("total"+" "+list.size()+" "+"words");
            // 遍历HashMap,统计单词出现的次数
            //Iterator是迭代器
            Iterator<String> iterator = hashMap.keySet().iterator();
            while (iterator.hasNext()) {
                String word = (String) iterator.next();
                //System.out.println(word + ":	" + hashMap.get(word));
                System.out.printf("%20s
",word + ":	" + hashMap.get(word));
            }
            buffer.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

功能二:CountDir()   按字母顺序排列

public void CountDir() {
        try {
            FileInputStream inputStream 
                = new FileInputStream(new File(path));
            BufferedReader buffer 
                = new BufferedReader(new InputStreamReader(inputStream));
            String lineword;
            String words ="";
            
            while((lineword=buffer.readLine())!=null) {
                words+=lineword;
            }
            //全部转换成小写,达到不区分大小写的目的
            String str=words.toString().toLowerCase();
            //分割字符串并存入数组
            String[] word = str.split("[^a-zA-Z0-9]|\ ");
            int num =0;
            Map<String,Integer> hashMap = new TreeMap<String,Integer>();    
            //Map<String,Integer> 是一对键值,遍历数组将其存入
            //String :存字符串 ;Integer 存数量
            for(int i=0 ;i<word.length ;i++) {          
                if(isLegal(word[i])) {    
                    if(hashMap.containsKey(word[i])) {
                        num = hashMap.get(word[i]);
                        hashMap.put(word[i], num+1);
                    }
                    else {
                        hashMap.put(word[i], 1);
                    }
                }
            }    
            //将map.entrySet()转换成list,输出总数量
            List<Map.Entry<String, Integer>> list 
            = new ArrayList<Map.Entry<String,Integer>>(hashMap.entrySet());
            //输出结果,map 具有字典排序的方法
            System.out.println("total"+"  "+list.size()+" words");
            for(int i=0;i<list.size();i++) {
                Map.Entry<String, Integer> e =list.get(i);
                System.out.printf("%20s
",e.getKey()+"  "+e.getValue());
            }
            buffer.close();
        }catch(FileNotFoundException e) {
            e.printStackTrace();
        }catch(IOException e) {
            e.printStackTrace();
        }
    }

功能三:CountNum(int n)对功能二进行降序排列

public void CountNum(int n) {
        try {
            // File类  读取文件内容
            FileInputStream inputStream = new FileInputStream(new File(path));
            BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream));
            String lineword;
            String words = null;
            //按行读取文件内容
            while((lineword=buffer.readLine())!=null) {
                words+=lineword+"
";
            }
            //toLowerCase():大写转换小写
            String str=words.toString().toLowerCase();    
            //分割字符串并存入数组
            String[] word = str.split("[^a-zA-Z0-9]|\ ");
            int num =0;
            Map<String,Integer> hasMap = new TreeMap<String,Integer>();
            //遍历数组将其存入Map<String,Integer>中
            for(int i=0;i<word.length;i++) {    
                //首先判断是否为合法单词        
                if(isLegal(word[i])) {
                    if(hasMap.containsKey(word[i])) {
                        num = hasMap.get(word[i]);
                        hasMap.put(word[i], num+1);
                    }
                    else {
                        hasMap.put(word[i], 1);
                    }
                }
            }
            //将map数组转换成list,易输出总数
            List<Map.Entry<String, Integer>> list =
                    new ArrayList<Map.Entry<String,Integer>>(hasMap.entrySet());
            //通过比较器实现排序
            Collections.sort(list,new Comparator<Map.Entry<String, Integer>>(){
                public int compare(Entry<String,Integer> e1,Entry<String,Integer> e2) {
                    return e2.getValue().compareTo(e1.getValue());
                }
            });
            //输出结果
            System.out.println("Total words is "+list.size());
            System.out.println("----------");
            for(int i=0;i<n;i++) {
                Map.Entry<String, Integer> e =list.get(i);
                System.out.printf("%20s
",e.getKey()+" "+e.getValue()); //对最后的排序结果 整齐排列
            }
            buffer.close();
        }catch(FileNotFoundException e) {
            e.printStackTrace();
        }catch(IOException e) {
            e.printStackTrace();
        }
    }

<二>、UseWordCount()  对以上类选择调用

package test_1;
import java.util.*;

public class UseWordCount {
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            String str = input.nextLine();
            //对输入的字符串进行分割
            String[] temp = str.split(" ");
            String path;
            int num = temp.length;
            //对输入的键入的字符串数量判断
            if(num==3) {
                if(temp[1].equals("-c")) {
                    path = temp[2];
                    WordCount test = new WordCount(path);
                    test.CountFile();
                }else if(temp[1].equals("-f")){
                    WordCount test = new WordCount();
                    path = test.readDir(temp[2]);
                    //System.out.println(temp[2]);
                    test.setpath(temp[2]+"\"+path);
                    test.CountDir();
                }else {
                    System.out.println("输入格式有错误");
                }
             //对功能三 传地址并判断  
            }else if(num==5) {
                //WordCount -f 文件路径 -n 数量
                if(temp[1].equals("-f") && temp[3].equals("-n")) {
                    WordCount test = new WordCount();
                    path = test.readDir(temp[2]);
                    test.setpath(temp[2]+"\"+path);
                    test.CountNum(Integer.parseInt(temp[4]));
                  //WordCount -c 文件名 -n 数量
                }else if(temp[1].equals("-c")&&
                    temp[3].equals("-n")) {
                    path=temp[2];
                    WordCount test = new WordCount(path);
                    test.CountNum(Integer.parseInt(temp[4]));
                    // WordCount -n 数量 -c 文件名
                }else if(temp[1].equals("-n")
                        &&temp[3].equals("-c")) {
                    path=temp[4];
                    WordCount test = new WordCount(path);
                    test.CountNum(Integer.parseInt(temp[2]));
                    // WordCount -n 数量 -f 文件名
                }else if(temp[1].equals("-n")
                        &&temp[3].equals("-f")) {
                    WordCount test = new WordCount();
                    path=test.readDir(temp[4]);
                    test.setpath(temp[4]+"\"+path);
                    test.CountNum(Integer.parseInt(temp[2]));
                }else {
                    System.out.println("输入格式有错误");
                }
            }else {
                System.out.println("输入格式有错误");
            }
            
            input.close();
        }
    }

结果展示:

第一次作业      第一次作业       第一次作业

  难点:

  对有些函数不理解,比如File方法,文件的读写难以理解,目前只能安部照用。JAVA有很多不同的函数,学会利用这些函数,对代码的理解度升高。比如:StringTokenizer来分割词,Map.Entry<String, Integer>键值使用,Iterator迭代器等。最后实现出来的结果统计错误,还得继续修改。

写代码的感受:

  功能一的所耗时间最久,一天。因为功能一是根本,其他的在功能一的基础上添加适合函数,于是我在网上找到词频统计的代码,理解其中各类函数的作用。对函数的理解耗费时间最久,第一次写功能一比较顺利,但是对输出文本排列整齐时出现问题,只能对数字排齐,暂时没有对单词排齐,到现在我依然没有找到问题在何处,我会继续对此找出解决问题。功能二时,起初没有发现Map自身具有字典排序,在网上找到相关的排序类,但是这种函数难以理解,我不懂如何在功能一正确调用该排序函数,后来依然是同学提醒我,Map类具有该功能,只需要改变输出方式。功能三相对前两个容易许多,

  写代码时,自己要有耐心,循序渐近,对函数一点点扣,并且使用,才能解决代码的问题,本次作业我最大的收获是写代码要有耐心,当出现错误时,自己得坚持,最后便会找到自己写代码坚持的点。