要求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类具有该功能,只需要改变输出方式。功能三相对前两个容易许多,
写代码时,自己要有耐心,循序渐近,对函数一点点扣,并且使用,才能解决代码的问题,本次作业我最大的收获是写代码要有耐心,当出现错误时,自己得坚持,最后便会找到自己写代码坚持的点。