20210326-软件工程作业-3-编程作业
这个作业属于哪个课程 | 软工-2018级计算机一班 |
---|---|
这个作业要求在哪里 | 20210326-软件工程作业-3-编程作业 |
这个作业的目标 | 学会代码规范,提升编程能力,熟悉gitee使用 |
学号 | 20188382 |
其他参考文献 | 码出高效_阿里巴巴JAVA开发手册 |
gitee仓库地址
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟 | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 15 | 15 |
Estimate | 估计这个任务需要多少时间 | 600 | 900 |
Development | 开发 | ||
Analysis | 需求分析 (包括学习新技术) | 100 | 120 |
Design Spec | 生成设计文档 | 90 | 90 |
Design Review | 设计复审 | 10 | 10 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 6 |
Design | 具体设计 | 60 | 90 |
Coding | 具体编码 | 360 | 480 |
Code Review | 代码复审 | 20 | 20 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 150 |
Reporting | 报告 | ||
Test Repor | 测试报告 | 60 | 60 |
Size Measurement | 计算工作量 | 30 | 60 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 60 |
合计 | 1520 | 2050 |
解题思路描述
<1>.文件数据的读入问题
拿出使得每次运行只需要读取数据一次,读取用的是BufferedReader,用read逐一读入;
<2>.字符数的统计
统计ASCII范围内字符后,进行范围的判断即可;
<3>.单词数的统计
先用正则表达式来分隔字符串,再用符合规则的正则表达式去匹配,最后用Map<String, Integer>来存储读取到的单词以及其对应的出现次数,为单词频率的排序提供数据;
<4>.有效行的统计
有效行的统计需要忽略空行,所以用正则表达式去匹配符合条件的行并统计行数;
<5>.出现频率top10单词的统计
top10单词的统计需要用到第三步所得到的Map<String, Integer>对象,通过用比较器对Map.entrySet转换的list进行排序,按照value值大小以及key的字典序进行排序;
<6>.数据输出到指定文件的问题
用BufferedWriter将拼接好的字符串按utf-8的方式输出到指定文件;
代码规范指定链接
设计与实验过程
主要的功能函数都放在Lib类中,对上述的六个问题用六个函数来解决
1.实现文件数据的读入,从最初的readline读入数据改为现在的read读入
public static String readFromFile(String filePath) {
int temp;
//创建输入流
BufferedReader br = null;
StringBuilder builder = null;
try {
br = new BufferedReader(new FileReader(filePath));
builder = new StringBuilder();
//按字符读入文件数据
while((temp = br.read()) != -1) {
builder.append((char)temp);
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
try {
br.close();
}catch(IOException e) {
e.printStackTrace();
}
}
return builder.toString();
}
2.字符数的判断只需判断其是否在ASCII的范围内即可
public static int getCharactersCount(String str) {
int count = 0;
char[] ch = str.toCharArray();
for(int i = 0; i < ch.length; i++) {
if(ch[i] >= 0 && ch[i] <= 127) {
count++;
}else continue;
}
return count;
}
3.单词数的统计以用split分割字符串,再用正则表达式匹配符合要求的单词,最后把单词存到Map中供排序使用,其中wordsMap是静态变量不用传入
public static int getWordsCount(String str) {
int count = 0;
//用正则表达式匹配分隔符分割字符串
String[] strs = str.split(BREAK_RE);
//遍历字符串数组,匹配符合正则表达式的单词
for(int i = 0; i < strs.length; i++) {
if(strs[i].matches(WORDS_RE)) {
//忽略大小写,添加单词到Map中
String temp = strs[i].toLowerCase();
if(wordsMap.containsKey(temp)) {
int num = wordsMap.get(temp);
wordsMap.put(temp, 1 + num);
}
else {
wordsMap.put(temp, 1);
}
count++;
}
}
return count;
}
4.行数的统计,也是用正则表达式去匹配即可
public static int getLineCount(String str) {
int count = 0;
Matcher matcher = Pattern.compile(LINE_RE).matcher(str);
while(matcher.find()) {
count++;
}
return count;
}
5.top10单词的排序,用比较器来实现
public static List<Map.Entry<String, Integer>> sortHashmap() {
//将words.entrySet()转换为list
List<Map.Entry<String, Integer>> list;
list = new ArrayList<Map.Entry<String, Integer>>(wordsMap.entrySet());
//通过比较器实现排序
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>(){
public int compare(Entry<String, Integer> m1, Entry<String, Integer> m2) {
//按照字典序以及value的值排序
if(m1.getValue().equals(m2.getValue())) {
return m1.getKey().compareTo(m2.getKey());
}else return m2.getValue()-m1.getValue();
}
});
return list;
}
6.用BufferedWriter将拼接的字符串传入指定文件
public static void writeToFile(int characters, int words, int lines, String filePath) {
//获取将要输出的字符串信息
String str = "characters: " + characters + "\nwords: " + words + "\nlines: " + lines +"\n";
List<Map.Entry<String, Integer>> list = sortHashmap();
int i = 0;
for(Map.Entry<String, Integer> map : list) {
if(i < 10) {
str += map.getKey() + ": " + map.getValue() + "\n";
i++;
}else break;
}
//得到输出流
FileOutputStream fos = null;
OutputStreamWriter writer = null;
BufferedWriter bw = null;
try {
fos = new FileOutputStream(filePath);
writer = new OutputStreamWriter(fos, "UTF-8");
bw = new BufferedWriter(writer);
bw.write(str);
bw.flush();
}catch(IOException e) {
e.printStackTrace();
}finally {
try {
fos.close();
writer.close();
bw.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
input:
output:
异常处理说明
异常情况,没有添加自己构造的异常类,主要的异常有FileNotFoundException和IOException两种,但运行时出现异常会输出异常数据。
心路历程与收获
了解Java对文件的操作,数据的输入输出的相关知识,而且是在不断地更新、调试的过程中学着用Gitee来存放和更新自己的代码。当然,在完成作业的途中中,查阅了诸多资料,自我也得到了很大的提升,与此同时,也与同学们进行了很多交流,查漏补缺。了解到了自己在编程里还存在着很多的不足。