第一次个人编程作业

Github项目地址

个人仓库

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 30
Estimate 估计这个任务需要多少时间 30 30
Development 开发 1485 1805
Analysis 需求分析 (包括学习新技术) 800 1000
Design Spec 生成设计文档 80 50
Design Review 设计复审 20 15
Coding Standard 代码规范 (为目前的开发制定合适的规范) 15 15
Design 具体设计 50 80
Coding 具体编码 400 500
Code Review 代码复审 20 25
Test 测试(自我测试,修改代码,提交修改) 100 150
Reporting 报告 40 50
Test Repor 测试报告 30 30
Size Measurement 计算工作量 10 20
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 50 70
合计 1555 1885

设计与实现

解题思路

  • 个人信息最终格式化成姓名,手机号,地址的格式
  • 将姓名和手机号从字符串上提取出来
  • 上网查找中国的行政划分,找出各级行政划分的关键词
  • 这样就能划分出大部分地址,缺失的地址用空串表示
  • 对于缺少省市关键词的,将地址和各省市比较(只比较每段信息的前两个字符)

程序设计

  • 程序总共分成了三个类
    • Main类,作为程序入口,调用AddressConvert类,读取和输出文件
    • AddressConvert类,对字符串进行转换,提取其中的姓名和手机号,对地址进行分割,其中调用了AddressFill类补全缺少省市的地址
    • AddressFill类,将地址信息和所有省市信息比对,找出相符的
  • 地址分割使用正则表达式
  • 地址的比先比较省再根据省比较市,提高查找效率

性能分析

刚开始对地址的比较,用到的数据是全都放在一起的,搜索市的时候会导致很多重复搜索,导致搜索的效率比较底下。经过改进,将代码改成了二级地址的匹配方式。
JProfiler生成的性能分析图如下:

单元测试

使用了JUnit对代码进行单元测试,主要是测试各个函数能否正常运行,设置了几组测试样例,测试程序对各种情况的处理。
测试数据主要有:

  • 缺少省和市的
  • 地级市和县级市同时存在的
  • 还有其他地址关键词冲突的

测试代码如下:

import static org.junit.Assert.*;
import org.junit.Test;

public class UnitTest {

	@Test
	public void testAddrFill_1() {
		String original="深圳";//市缺失,只比较前两个字
		String changed="深圳市";
		assertEquals(AddressJudge.addrFill(original), changed);
	}
	@Test
	public void testAddrConvert_2() throws Exception {
		//省市缺失
		String original="1!张三,福建福州闽13599622362侯县上街镇福州大学10#111.";
		String changed="{\"姓名\":\"张三\",\"手机\":\"13599622362\",
                \"地址\":[\"福建省\",\"福州市\",\"闽侯县\",\"上街镇\",\"福州大学10#111\"]}";
		assertEquals(AddressBasic.addrConvert(original), changed);
	}
	@Test
	public void testAddrConvert_3() throws Exception {
		//地级市和县级市同时存在
		String original="1!风清扬,福建省福州市福13599622362清市上迳镇小东林.";
		String changed="{\"姓名\":\"风清扬\",\"手机\":\"13599622362\",
                \"地址\":[\"福建省\",\"福州市\",\"福清市\",\"上迳镇\",\"小东林\"]}";
		assertEquals(AddressBasic.addrConvert(original), changed);
	}
	@Test
	public void testAddrConvert_4() throws Exception {
		//直辖市+单级地址缺失
		String original="3!小美,北京市东15822153326城区交道口东大街1号北京市东城区人民法院.";
		String changed="{\"姓名\":\"小美\",\"手机\":\"15822153326\",\"地址\":[\"北京\",\"
                北京市\",\"东城区\",\"\",\"交道口东大街\",\"1号\",\"北京市东城区人民法院\"]}";
		assertEquals(AddressBasic.addrConvert(original), changed);
	}
	@Test
	public void testAddrConvert_5() throws Exception {
		//省市缺失
		String original="1!张三,福建福州闽13599622362侯县上街镇福州大学10#111.";
		String changed="{\"姓名\":\"张三\",\"手机\":\"13599622362\",
                \"地址\":[\"福建省\",\"福州市\",\"闽侯县\",\"上街镇\",\"福州大学10#111\"]}";
		assertEquals(AddressBasic.addrConvert(original), changed);
	}
	@Test
	public void testAddrConvert_6() throws Exception {
		//地级市和县级市同时存在
		String original="1!风清扬,福建省福州市福13599622362清市上迳镇小东林.";
		String changed="{\"姓名\":\"风清扬\",\"手机\":\"13599622362\",
                \"地址\":[\"福建省\",\"福州市\",\"福清市\",\"上迳镇\",\"小东林\"]}";
		assertEquals(AddressBasic.addrConvert(original), changed);
	}
	@Test
	public void testAddrConvert_7() throws Exception {
		//自治区和区同时存在
		String original="1!令狐冲,内蒙古自治区呼和13599622362浩特市新城区内蒙古工业大学.";
		String changed="{\"姓名\":\"令狐冲\",\"手机\":\"13599622362\",
                \"地址\":[\"内蒙古自治区\",\"呼和浩特市\",\"新城区\",\"\",\"内蒙古工业大学\"]}";
		assertEquals(AddressBasic.addrConvert(original), changed);
	}
}

单元测试覆盖率:

异常处理

异常处理主要是设置在文件读写部分的,
代码如下:

try {
	fis = new FileInputStream("d:/1.txt");
	isr = new InputStreamReader(fis, "UTF-8");
	br = new BufferedReader(isr);
	fos = new FileOutputStream("d:/2.txt");
	osw = new OutputStreamWriter(fos, "UTF-8");
	bw = new BufferedWriter(osw);
	String line=br.readLine();
	bw.write("["+AddressBasic.addrConvert(line));
	while ((line = br.readLine()) != null)
	{
		bw.write(",");
		bw.newLine();
		bw.write(AddressBasic.addrConvert(line));
	}
	bw.write("]");
} catch (Exception ex) {
	ex.printStackTrace();
}
posted @ 2019-09-17 22:49  annahme  阅读(161)  评论(3编辑  收藏  举报