寒假作业(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);
    }
	}

 


Part5.单元测试

posted @ 2020-02-18 22:48  -矛与盾  阅读(285)  评论(2编辑  收藏  举报