结对作业二——WordCount进阶版
软工作业三
要求地址
PSP表格
| PSP2.1 | 个人开发流程 | 预估耗费时间(分钟) | 实际耗费时间(分钟) | 
|---|---|---|---|
| Planning | 计划 | 10 | 7 | 
| · Estimate | 明确需求和其他相关因素,估计每个阶段的时间成本 | 10 | 7 | 
| Development | 开发 | 275 | 240 | 
| · Analysis | 需求分析 (包括学习新技术) | 40 | 35 | 
| · Design Spec | 生成设计文档 | 10 | 10 | 
| · Design Review | 设计复审 | 5 | 5 | 
| · Coding Standard | 代码规范 | 10 | 10 | 
| · Design | 具体设计 | 30 | 20 | 
| · Coding | 具体编码 | 120 | 120 | 
| · Code Review | 代码复审 | 30 | 20 | 
| · Test | 测试(自我测试,修改代码,提交修改) | 30 | 20 | 
| Reporting | 报告 | 90 | 90 | 
| · | 测试报告 | 40 | 40 | 
| · | 计算工作量 | 20 | 20 | 
| · | 并提出过程改进计划 | 30 | 30 | 
解题思路描述
在代码上,和小伙伴两个人的其实没有什么优劣之分。因为主要由我来实现新功能,所以两个人决定采用我的代码。
关于新增功能:
- 词组统计:首先将按行读取的字符串连接成一串字符串。通过正则表达式分割单词并放入字符数组中。从第一个单词开始计算以该单词为首的词组及其词频。
 - 自定义输出:将上次作业中的Count类中的WordTop函数中加入参数n,将原来函数中定死的“10”改为参数n。
 
设计实现过程
一、相关类的设计
- File类:读取文件数据,写入数据到文件
 - Count类:统计函数的实现
 - Main类:其他类和函数的调用
 
二、相关函数的设计
1. File类:
- readfile函数:从文件中按行读取数据并保存到ArrayList中
 - writefile函数:将统计得到的结果写入文件中
 
2. Count类:
- CountChars函数:统计文本字符数
 - CountWords函数:统计文本合法单词数
 - CountLine函数:统计文本合法行数
 - WordTop函数:统计最多的10个单词及其词频
 - CountPhrase函数:统计词组
 
代码说明
1. 实现命令行参数设定输入
String in=null;  //初始化变量
String out=null;
int m=0,n=0;
for(int i=0;i<args.length;i++){
	if("-i".equals(args[i])){ //若为“-i”,索引+1,将所带参数值赋值给in
		i++;
		in=args[i];
	}
	if("-m".equals(args[i])){ //若为“-m”,索引+1,将所带参数值赋值给m
		i++;
		m=Integer.parseInt(args[i]);
	}
	if("-n".equals(args[i])){ //若为“-n”,索引+1,将所带参数值赋值给n
		i++;
		n=Integer.parseInt(args[i]);
	}
	if("-o".equals(args[i])){ //若为“-o”,索引+1,将所带参数值赋值给out
		i++;
		out=args[i];
	}
}
2. CountChars函数:
public int CountChars(){ //统计文本字符数
		int count=0;
		for(int i=0;i<line.size();i++){ //遍历文本数据
			String str=line.get(i);
			for(int j=0;j<str.length();j++){ //遍历每行字符串
				char c=str.charAt(j);  //转换成字符
				if(('A'<=c&&c<='Z')||('a'<=c&&c<='z')||c=='\n'||c=='\r'||c=='\t'){
					count++; //若为合法字符则计数
				}
			}
		}
		return count;
	}
3. CountWords函数:
public int CountWords(){ //统计文本合法单词数
		int count=0;
		for(int i=0;i<line.size();i++){ //遍历文本数据
			String str=line.get(i);
			if(str.length()>=4){ //若该行字符串长度大于等于4,则该行可能存在合法单词
				String[] words=str.split("[^a-zA-Z0-9]+"); //通过正则表达式匹配分隔符来分割字符串
				for (String word:words){ //遍历分割后的字符串数组
					int flag=0; //标识符标识是否为合法单词
					char[] w=word.toCharArray();
					for(int j=0;j<4;j++){ //遍历字符串数组的前四个字符
						if(!(('A'<=w[j]&&w[j]<='Z')||('a'<=w[j]&&w[j]<='z'))){
							flag=1;
							break; //若不为英文字母则标识符赋值为1并跳出循环
						}
					}
					if(flag==0){ //若为合法单词
						if(!map.containsKey(word)){ //该单词第一次出现
							count++; //单词数加1
							map.put(word, 1); //将键、值添加进map中
						}
						else{
							int num=map.get(word); //该单词已出现过
							map.put(word, ++num); //单词词频加1
						}
					}
				}
			}
		}
		return count;
	}
4. CountLine函数:
public int CountLine(){ //统计文本合法行数
		int count=0;
		for(int i=0;i<line.size();i++){ //遍历文本数据
			String str=line.get(i);
			if(str.length()>0){ //若该行字符串长度大于0,则计数
				count++;
			}
		}
		return count;
	}
5. WordTop函数:
public ArrayList WordTop(int count){ //统计最多的10个单词及其词频
		ArrayList<Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet()); //定义一个list来存放排序后的单词及其词频
		Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { //重写比较器的排序函数
            @Override
            public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
                if (o1.getValue() == o2.getValue()) {
                    return o1.getKey().compareTo(o2.getKey());
                }
                return o2.getValue() - o1.getValue();
            }
        });
		if(count<=10){ //若单词数不大于10,则直接返回排序后的list
			return list;
		}
		else{ //若单词数大于10,则将第10位以后的单词从list中移除再返回list
			for(int i=list.size();i>=10;i--){
				list.remove(i);
			}
			return list;
		}
	}
6. CountPhrase函数:
public Map CountPhrase(int m){  //词组统计
		String str=null;
		for(int i=0;i<line.size();i++){  //将按行读取得到的字符串列表连接成一串字符串
			String s=line.get(i);
			if(i==0){
				str=s;
			}
			else{
				str=str+" "+s;
			}
		}
		System.out.println(str);
		String[] words=str.split("[^a-zA-Z0-9]+");  //通过正则表达式匹配分隔符来分割字符串
		for (int i=0;i<words.length;i++){  //从每个分割出来的字符串开始计算词组
			int flag=0; //定义标识符标识是否为单词
			int p=i; //记录当前遍历的字符串索引
			String s=words[p].toLowerCase();
			if(map.containsKey(s)){ //若当前字符串为单词
				String phrase=s;
				for(int j=1;j<m;j++){  //连接单词为词组
					p++;
					if(((p)<words.length)&&(map.containsKey(words[p]))){
						phrase=phrase+" "+words[p];
						System.out.println(p);
					}
					else{
						flag=1; //若连续单词个数不满足设定的词组则跳出循环
						break;
					}
				}
				if(flag==0){  //将词组及其数量添加到map中
					if(!map2.containsKey(phrase)){
						map2.put(phrase, 1);
					}
					else{
						int num=map2.get(phrase);
						map2.put(phrase, ++num);
					}
				}
			}
		}
		return map2;
	}
感受
这次结对编程我主要负责新增功能的实现。新增功能的实现并没有什么难度,主要是新增一个功能函数,以及对原有代码进行一些小更改。之前的代码里读入文件路径是定死的,确实是没有考虑到非代码编写者的使用感受。新增功能函数的实现上面已经有具体内容了,这里就不赘述了。因为个人比较喜欢开发这块,而且对于测试没有太大兴趣,队友恰好比较喜欢,两人一拍即合,愉快地分工,整个合作过程还是很融洽的。虽然国庆期间相隔两地,但还是坚持通过视频聊天等等手段完成本次作业,精神可嘉。
结对作业二——WordCount进阶版的更多相关文章
- 结对作业(1.0版)(bug1已修复)
		
import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing ...
 - 结对作业——WordCount进阶版
		
Deadline: 2018-10-7 22:00PM,以博客提交至班级博客时间为准 要求参考来自:https://www.cnblogs.com/xinz/archive/2011/11/27/22 ...
 - 结对作业-WordCount进阶版
		
1.在文章开头给出博客作业要求地址. 博客园地址:https://www.cnblogs.com/happyzm/p/9559372.html 2.给出结对小伙伴的学号.博客地址,结对项目的码云地址. ...
 - 作业二Wordcount
		
1,github地址 https://github.com/dtneverdie/word-count 2,PSP表格 3,解题思路 先从理论上判断应该先将文件内的字符全部读入,然后根据分隔符来进行单 ...
 - python三级菜单实例(傻瓜版和进阶版)
		
程序: python三级菜单 要求: : 1.打印省.市.县三级菜单 2.可返回上一级 3.可随时退出程序 方案一:傻瓜版(其实傻瓜版考察的主要是思路!思路清楚了,那才不是傻瓜!O(∩_∩)O哈哈~) ...
 - 软工实践——结对作业2【wordCount进阶需求】
		
附录: 队友的博客链接 本次作业的博客链接 同名仓库项目地址 一.具体分工 我负责撰写爬虫爬取信息以及代码整合测试,队友子恒负责写词组词频统计功能的代码. 二.PSP表格 PSP2.1 Persona ...
 - 结对第2次作业——WordCount进阶需求
		
作业题目链接 队友链接 Fork的同名仓库的Github项目地址 具体分工 玮哥负责命令参数判断.单词权重统计,我只负责词组词频统计(emmmm). PSP表格 预估耗时(分钟) 实际耗时(分钟) P ...
 - 结队第二次作业——WordCount进阶需求
		
结队第二次作业--WordCount进阶需求 博客地址 051601135 岳冠宇 博客地址 051604103 陈思孝 博客地址 Github地址 具体分工 队友实现了爬虫功能,我实现了wordco ...
 - 结对作业1----基于flask框架的四则运算生成器
		
011.012结对作业 coding地址:https://coding.net/u/nikochan/p/2nd_SE/git 一.作业描述 由于上次作业我没有按时完成,而且庞伊凡同学编程能力超棒,所 ...
 
随机推荐
- php_Trait
			
* Trait Answer* Trait : 关键字 Trait* 使用 use* 我的理解 是为了解决php不能多继承的一个处理方式* 在使用的时候 可以让两个不相关的类 产生联系* Trait ...
 - day30 进程
			
推荐两本书:现代操作系统和操作系统原来,学习好python以后再去研究. 并发:任务的切换,保存状态,存在io的是实现空间和时间的 重复利用 操作系统的发展历史: 第一代(1940-1955)手工 ...
 - Spring Cloud之 Config Server 使用ip端口号配置高可用
			
先看官方文档的配置 --- spring: profiles: peer1 eureka: instance: hostname: peer1 client: serviceUrl: defaultZ ...
 - DXP常用的设置及快捷键
			
原文地址:http://www.cnblogs.com/NickQ/p/8799240.html 测试环境:Altium Designer Summer 16 一.快捷键 1.原理图和PCB通用快捷键 ...
 - C语言链接属性总结
			
1.什么是链接属性? 当组成一个程序的各个源文件分别被编译后,所有的目标文件以及那些从一个或多个函数库中引用的函数链接在一起,形成可执行程序. 标识符的链接属性决定如何处理在不同文件中出现的标识符 ...
 - Jetson tx2 串口通信
			
主要参考了这篇博客:https://blog.csdn.net/zomb1e0117/article/details/85157014 其中需要注意的是最后的时候cutecom端口需要把设备改为:/d ...
 - 实现一个带有指纹加密功能的笔记本(Android)第二部分
			
上文基本完成了整个笔记本的笔记功能的实现,接下来记录实现指纹识别加密以及一些小注意事项. 首先判断该手机是否具备指纹识别的硬件功能和用户是否开启指纹识别. public boolean isFinge ...
 - 长沙Uber优步司机奖励政策(12月14日到12月20日)
			
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
 - 手写ORM第一版
			
ORM第一版: #Author = __rianley cheng__ #ORM 简易版 from mysql_ import Mysql class Fileld: def __init__(sel ...
 - 如果看懂git -help
			
每一个git 命令,都可以git * --help 打开git 的网页去看详细内容,也可以git * -help 在当前命令行里面看. 如下: zy@caoxinyu MINGW64 /f/git/i ...