写在前面
Part1.PSP表格
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
50 |
35 |
Estimate |
估计这个任务需要多少时间 |
800 |
1200 |
Development |
开发 |
755 |
1145 |
Analysis |
需求分析 (包括学习新技术) |
90 |
90 |
Design Spec |
生成设计文档 |
30 |
30 |
Design Review |
设计复审 |
20 |
15 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
10 |
10 |
Design |
具体设计 |
40 |
70 |
Coding |
具体编码 |
505 |
855 |
Code Review |
代码复审 |
30 |
45 |
Test |
测试(自我测试,修改代码,提交修改) |
30 |
30 |
Reporting |
报告 |
45 |
55 |
Test Report |
测试报告 |
15 |
20 |
Size Measurement |
计算工作量 |
10 |
10 |
Postmortem & Process Improvement Plan |
事后总结, 并提出过程改进计划 |
20 |
25 |
total |
合计 |
850 |
1235 |
Part2.解题思路
需求分析
- 实现对命令行参数的识别
- 从指定目录下,读取输入日期
xxxx-xx-xx
以及之前的疫情文件,同时确保读取的文件符合命名规则 年-月-日.log.txt
并根据不同省份处理数据
- 根据参数
-type
和 -province
的值将统计结果打印到指定的文件中
实现思路
- 从需求上看,解题的思路比较简单,只需要依照不同的正则表达式,匹配相应的病例增减数据,再根据省份信息,将对响应数据进行计算,最后根据参数要求,格式化输出统计结果即可
- 程序设计过程如下图
Prat3.设计实现过程
数据结构
- 用四个数组存放全国及各省的感染人数、疑似人数、治愈人数、死亡人数,用一个字符串数组存放省市名,方便数据分析时对下表的定位
ip = new int[PROVIENCE_NUM];
sp = new int[PROVIENCE_NUM];
cure = new int[PROVIENCE_NUM];
dead = new int[PROVIENCE_NUM];
provience_array = new String[] {"全国","安徽","北京","重庆","福建","甘肃","广东","广西",
"贵州","海南","河北","河南","黑龙江","湖北","湖南","吉林","江苏","江西","辽宁","内蒙古",
"宁夏","青海","山东","山西","陕西","上海","四川","天津","西藏","新疆","云南","浙江"};
- 申请两个字符串向量用于存放参数
-province
和 -type
的值,另外用一个布尔型数组用于判断某个省份是否要输出疫情信息
flg = new boolean[PROVIENCE_NUM];
cmd4type = new Vector<String>();
cmd4provience = new Vector<String>();
流程图
- 从思路分析可以看出程序应该依次实现参数读取、文件匹配、数据读取、数据统计、数据输出这几个功能,其中做主要的是文件匹配及数据读取,流程图如下
Part.4核心代码说明
public void getArgument() {
for(int i = 1; i < argc; i++) {
if(argv[i].equals("-log")) {
i++;
dir4log = argv[i];
} else if(argv[i].equals("-out")) {
i++;
dir4out = argv[i];
} else if(argv[i].equals("-data")) {
i++;
cmd4data = argv[i] + ".log.txt";
flg4data = true;
} else if(argv[i].equals("-type")) {
flg4type = true;
while(!argv[i].startsWith("-")) {
cmd4type.add(argv[i]);
i++;
if(argv[i].startsWith("-")) {
i--;
break;
}
}
} else if(argv[i].equals("-provience")) {
flg4provience = true;
while(!argv[i].startsWith("-")) {
//System.out.println(argv[i]);
cmd4provience.add(argv[i]);
i++;
if(argv[i].startsWith("-")) {
i--;
break;
}
}
}
}
}
- 函数
getPath(String pah)
用于获取并筛选符合格式的条件名
public List<String> getPath(String path) {
List<String> files = new ArrayList<String>();
File file = new File(path);
File[] tempList = file.listFiles();
String rexp1 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9]" +
"[0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|" +
"[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))" +
"|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|" +
"[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26" +
"])00))-02-29))\.log\.txt";
for (int i = 0; i < tempList.length; i++) {
if (tempList[i].getName().matches(rexp1) == true && tempList[i].isFile()) {
if(flg4data == true && tempList[i].getName().compareTo(cmd4data) <= 0) {
files.add(tempList[i].toString());
} else if(flg4data == false) {
files.add(tempList[i].toString());
}
}
}
return files;
}
headleData(String dataLine)
用于匹配相应数据
public void headleData(String dataLine) {
String status1 = "(\S+) 新增 感染患者 (\d+)人";
String status2 = "(\S+) 感染患者 流入 (\S+) (\d+)人";
String status3 = "(\S+) 治愈 (\d+)人";
String status4 = "(\S+) 死亡 (\d+)人";
String status5 = "(\S+) 新增 疑似患者 (\d+)人";
String status6 = "(\S+) 疑似患者 流入 (\S+) (\d+)人";
String status7 = "(\S+) 疑似患者 确诊感染 (\d+)人";
String status8 = "(\S+) 排除 疑似患者 (\d+)人";
if(dataLine.matches(status1)) {
ip_inc(dataLine);
} else if(dataLine.matches(status2)) {
ip_flow(dataLine);
} else if(dataLine.matches(status3)) {
ip_cure(dataLine);
} else if(dataLine.matches(status4)) {
ip_die(dataLine);
} else if(dataLine.matches(status5)) {
sp_inc(dataLine);
} else if(dataLine.matches(status6)) {
sp_flow(dataLine);
} else if(dataLine.matches(status7)) {
sp_conf(dataLine);
} else if(dataLine.matches(status8)) {
sp_exclude(dataLine);
}
}
Part5.单元测试