第一次个人编程作业

1、github项目地址

2、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时
(分钟)
实际耗时
(分钟)
Planning 计划 30 30
· Estimate · 估计这个任务需要多少时间 30 30
Development 开发 1900 2410
· Analysis · 需求分析 (包括学习新技术) 1200 1000
· Design · 生成设计文档 30 20
· Design Review · 设计复审 20 10
· Coding Standard · 代码规范 (为目前的开发制定或选择合适的规范) 10 10
· Design · 具体设计 60 40
· Coding · 具体编码 360 1200
· Code Review · 代码复审 100 30
· Test · 测试(自我测试,修改代码,提交修改) 120 100
Reporting 报告 110 35
· Test Report · 测试报告 60 10
· Size Measurement · 计算工作量 10 5
· Postmortem & Process Improvement Plan · 事后总结, 并提出改进计划 40 20
  · 合计 2040 2475

3、计算模块接口的设计与实现过程

选择编程语言

Java

思考

刚看到这个题目的时候很懵,不知道如何下手。需要学习的新技术也很多,在查找了相关资料后,我发现用java实现比较容易,于是java的学习也添进了计划中。接下来花大量时间学习了很多教程。浏览了网上关于java实现地址分割的文章后,我从里面的List使用想到了方向,设计好如下所示的解题思路和设计后,就开始了编码。
待学习:java语法、json文件格式、code quality analysis、studio profiling tools、单元测试、使用插件查看覆盖率等指标、上传代码到github......

代码组织

(1)类和函数

类名 属性 函数名
Main main
partitionI name,telephone,address getName,getTelephone
partition1
(作为partitionI的子类)
city,county,town,detail,detailstreet,detailnum addressResolution1, addressResolution2,show

(2)解题思路

  • 先从键盘输入一条数据
  • 取名字
  • 取号码
  • 分割地址
  • 转json格式输出
  • 改成读写文件形式

(3)实现过程

  • 在main函数中读入文件,利用字符串数组处理每一行的信息,用一个function标志区分实现哪一功能(五级or七级地址)。
  • 编写getName函数获取name,编写getTelephone函数获取telephone。使用String相关函数和for循环可以实现定位和提取。
  • 修改字符串使之只剩地址信息,在addressResolution1函数和addressResolution2函数中利用正则表达式给address赋值
  • 在show函数中利用LinkedHashMap分别给"姓名"、"手机"、"地址"匹配name,telephone,address,最后装到List中
  • 将List转换为json格式输出到文件中

算法关键和独到之处

  • 提取和定位字符串用到split、substring、indexOf、charAt等String类的函数,用for循环找到连续的11个数字定位手机号。
  • 利用正则表达式分割地址字符串,并匹配。
  • address的类型是ArrayList;匹配元素用到LinkedHashMap。

项目关键代码

String regex="(?<province>[^省]+自治区|.*?省|.*?行政区|.*?市)(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市|.*?县)(?<county>[^县]+县|.+区|.+市|.+旗|.+海域|.+岛)?(?<town>[^区]+区|.+镇|.+乡|.+街道)?(?<detailstreet>.[^路]+路|.+道|.+街|.+巷|.+胡同|.+里弄|.+弄)?(?<detailnum>.[^号]+号)?(?<detail>.*)";
Matcher m=Pattern.compile(regex).matcher(ogdata);
JSONArray json = new JSONArray(table);
m.writeFile(json.toString());

4、计算模块接口部分的性能改进

改进思路

在编码过程中遇到很多bug,主要通过查找资料解决。

性能分析图


5、计算模块部分单元测试展示

测试的函数和构造测试数据的思路

  • test1测试getName,test2测试getTelephone
  • test3~test9测试不同情况下的地址分割,选择五级或七级的地址分割,结合所给测试样例和网上查找的地名测试

代码


    @Test
	public void test1() {
		partition1 person = new partition1();
		assertTrue(person.getName(4,"1!李四,福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层").equals("李四"));
	}


	@Test
	public void test2() {
		partition1 person = new partition1();
		assertTrue(person.getTelephone(16,"福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层").equals("13756899511"));
	}

	@Test
	public void test3() {
		partition1 person = new partition1();
		person.addressResolution1("福建省福州市鼓楼区鼓西街道湖滨路110号湖滨大厦一层");
		ArrayList<String> answer =new ArrayList<String>();
		answer.add("福建省");answer.add("福州市");answer.add("鼓楼区");answer.add("鼓西街道");answer.add("湖滨路110号湖滨大厦一层");
		boolean test = true;
		for (int j = 0; j < answer.size(); j++) 
		{
			String obj =answer.get(j);
			if (!person.address.contains(obj))
				{
					test=false;
				}
		}
		assertTrue(test);
	}
	
	@Test
	public void test4() {
		partition1 person = new partition1();
		person.addressResolution1("福建省福州市鼓楼区五一北路123号福州鼓楼医院");
		ArrayList<String> answer =new ArrayList<String>();
		answer.add("福建省");answer.add("福州市");answer.add("鼓楼区");answer.add("");answer.add("五一北路123号福州鼓楼医院");
		boolean test = true;
		for (int j = 0; j < answer.size(); j++) 
		{
			String obj =answer.get(j);
			if (!person.address.contains(obj))
				{
					test=false;
				}
		}
		assertTrue(test);
	}
	
	@Test
	public void test5() {
		partition1 person = new partition1();
		person.addressResolution2("广东省东莞市凤岗镇凤平路13号");
		ArrayList<String> answer =new ArrayList<String>();
		answer.add("广东省");answer.add("东莞市");answer.add("");answer.add("凤岗镇");answer.add("凤平路");answer.add("13号");
		boolean test = true;
		for (int j = 0; j < answer.size(); j++) 
		{
			String obj =answer.get(j);
			if (!person.address.contains(obj))
				{
					test=false;
				}
		}
		assertTrue(test);
	}

	@Test
	public void test6() {
		partition1 person = new partition1();
		person.addressResolution1("北京市东城区交道口东大街1号北京市东城区人民法院");
		ArrayList<String> answer =new ArrayList<String>();
		answer.add("北京");answer.add("北京市");answer.add("东城区");answer.add("");answer.add("交道口东大街1号北京市东城区人民法院");
		boolean test = true;
		System.out.println(person.address);
		for (int j = 0; j < answer.size(); j++) 
		{
			String obj =answer.get(j);
			if (!person.address.contains(obj))
				{
					test=false;
				}
		}
		assertTrue(test);
	}
	
	@Test
	public void test7() {
		partition1 person = new partition1();
		person.addressResolution2("福建省福州市鼓楼区鼓西街道湖滨路110号湖滨大厦一层");
		ArrayList<String> answer =new ArrayList<String>();
		answer.add("福建省");answer.add("福州市");answer.add("鼓楼区");answer.add("鼓西街道");answer.add("湖滨路");answer.add("110号");answer.add("湖滨大厦一层");
		boolean test = true;
		for (int j = 0; j < answer.size(); j++) 
		{
			String obj =answer.get(j);
			if (!person.address.contains(obj))
				{
					test=false;
				}
		}
		assertTrue(test);
	}

	@Test
	public void test8() {
		partition1 person = new partition1();
		person.addressResolution2("江苏省苏州市姑苏区寒山寺弄24号");
		ArrayList<String> answer =new ArrayList<String>();
		answer.add("江苏省");answer.add("苏州市");answer.add("姑苏区");answer.add("");answer.add("寒山寺弄");answer.add("24号");answer.add("");
		boolean test = true;
		for (int j = 0; j < answer.size(); j++) 
		{
			String obj =answer.get(j);
			if (!person.address.contains(obj))
				{
					test=false;
				}
		}
		assertTrue(test);
	}
	
	@Test
	public void test9() {
		partition1 person = new partition1();
		person.addressResolution2("福建省宁德市东侨经济开发区东湖路19号");
		ArrayList<String> answer =new ArrayList<String>();
		answer.add("福建省");answer.add("宁德市");answer.add("东侨经济开发区");answer.add("");answer.add("东湖路");answer.add("19号");answer.add("");
		System.out.println(person.address);
		boolean test = true;
		for (int j = 0; j < answer.size(); j++) 
		{
			String obj =answer.get(j);
			if (!person.address.contains(obj))
				{
					test=false;
				}
		}
		assertTrue(test);
	}
	
	@Test
	public void test10() {
		partition1 person = new partition1();
		person.addressResolution1("福建福州闽侯县上街镇福州大学10#111");
		ArrayList<String> answer =new ArrayList<String>();
		answer.add("福建省");answer.add("福州市");answer.add("闽侯县");answer.add("上街镇");answer.add("福州大学10#111");
		System.out.println(person.address);
		boolean test = true;
		for (int j = 0; j < answer.size(); j++) 
		{
			String obj =answer.get(j);
			if (!person.address.contains(obj))
				{
					test=false;
				}
		}
		assertTrue(test);
	} 

测试覆盖率和正确率截图

有一些缺省的地址信息还无法做到正确的匹配。

6、计算模块部分异常处理说明

对输入输出做了异常处理,防止输入非法文件。

7、心路历程与收获

一开始,我连题目都没看懂,对开始完成这道题目完全没有信心和思路。经过两天的熟悉,大概知道了学习的方向。因为没学过java,开始疯狂学习有关java的入门知识。确定思路后,我进行了简单的设计就开始了编码,这也是我做的不足的地方,导致分类和函数还是有点乱,实现方法也不佳。由于编程能力的薄弱和语法的陌生,编码过程频频出错,需要依靠大量的搜索和运行输出发现问题。经过三天的编码和纠错,终于实现了一部分题目要求。这一周,我的最大收获是学会细化任务,将看似困难的任务分解为貌似可以做到的小任务。此外,我学会了很多新的技术,对整个开发流程有了一定的熟悉。需要改进的地方是今后要加强编程练习,并且要学会设计流程更规范化,还要接触很多需要学习的新知识。
第一次个人编程作业几乎填满了我这一周所有的空闲时间,还开启了熬夜模式,过程很累,但也学到了很多。(没有什么是一个熬夜解决不了的,如果有,就来六个!)

原文地址:https://www.cnblogs.com/cjw1007/p/11536567.html