要求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 | |
Coding | 具体编码 | 480 | 600 |
Code Review | 代码复审 | ||
Test | 测试(自我测试,修改代码,提交修改) | 120 | |
Reporting | 报告 | 180 | 210 |
Size Measurement | 计算工作量 | ||
Postmortem & Process Improvement Plan | 事后总结, 提出过程改进计划 |
功能模块 | 预计时间(min) | 实际时间(min) |
功能1 | One day | 150 |
功能2 | 140 | |
功能3 | ||
测试功能 | 30 |
要求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 + ":\t" + hashMap.get(word));
System.out.printf("%20s\n",word + ":\t" + 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\n",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+"\n";
}
//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\n",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类具有该功能,只需要改变输出方式。功能三相对前两个容易许多,
写代码时,自己要有耐心,循序渐近,对函数一点点扣,并且使用,才能解决代码的问题,本次作业我最大的收获是写代码要有耐心,当出现错误时,自己得坚持,最后便会找到自己写代码坚持的点。