寒假作业(2/2)——疫情统计
写在前面
这个作业属于哪个课程 | <班级的链接> |
---|---|
这个作业要求在哪里 | <作业要求的链接> |
这个作业的目标 | 创建熟悉使用Github,编写基于命令行运行的程序 |
作业正文 | 正文如下 |
其他参考文献 | 寒假第二次作业引导和提示 |
Github仓库地址 | https://github.com/maoyudun/InfectStatistic-main |
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核心代码说明
getArgument()
函数,用于处理输入参数
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);
}
}