zoukankan      html  css  js  c++  java
  • 第一次个人编程作业

    一、仓库地址

    二、PSP表格

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

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

    (1)解题思路

    思考和找资料过程:

      刚打开作业的时候,天花乱坠的要求直接把我整懵了,头晕,再打开,还是头晕。逃避了一会,想着早点看懂题目能够早点开始,决定看个大概之后,从代码着手:
      1.题目中的数据是姓名、手机号和地址这三个字符串和一些标点符号的组合,而题目要求我们将其分开,同时去掉一些标点,我想着是否有一些方法能够去把这些字符串分开,向大佬寻求帮助后得知可以使用Java的正则表达式,于是去慕课和一些博客中学习了相关知识。
      2.之后想着如果通过正则表达式能够将姓名、手机号和地址分开的话,应该也能够再利用它来对地址进行详细的划分,果不其然,正则表达式真是个好东西(激动地搓搓手。
      3.接着就是仔细分析代码需求了,在这上面真是走了不少弯路。大致了解了三个level的要求,首先level1是要求对地址进行五级划分,而level2和level3则是七级划分,level1和level2都会出现“省”和“市”这两个字符会缺失的情况,而level3和它们根本不是一个level,它会出现缺失,甚至需要补全,了解到需要导入地图,ok fine,我先放弃这个,能把level1和level2打出来,再尝试一下去解决补全的问题,对于不同级别的不同情况,我打开了淘宝,选择设置收货地址,随手点一点找了一下不同的情况。
      再之后考虑的就是github和其他要求里面需要下载的软件的使用了,也是跟着几篇博客里面的教程一步一步做下来。同时感觉很幸运有认识的好友是学计算机的,我从他们那里获得了不少帮助,也很感谢班上认真解答我的疑问的同学。

    解题步骤

    Step 1. 利用正则表达式将前缀x!,姓名,手机号和地址分开
    Step 2. 通过分离出来的前缀x判断进行什么级别的地址划分
    Step 3. 利用正则表达式判断是否为直辖市并且分割剩余的详细地址

    (2)设计实现过程

      我利用Java来写这个程序。由于都是字符串切割这一类问题,我只用了一个类。类中有一个main方法和其他几种工具方法和输出方法,在main方法中先对字符串进行切割,把前缀x,姓名,手机号和地址分开后,先调用getProvince方法判断是否有省级或者市级的级别后缀缺失,再根据前缀x的不同,调用了不同的方法进行地址的详细划分,最后通过输出函数输出。以下是几个方法:

    方法

    方法名 说明
    Map<String, Object> getJson(ArrayList arrayList,String name,String phone) 输出函数
    ArrayList getMatchesAddress (String address) 工具函数:用于进行Level1的详细地址划分
    ArrayList getMatchesAddressSeven (String address) 工具函数:用于进行Level2和Level3的详细地址划分
    ArrayList getProvince(String address) 工具函数:用于解决缺少省、市等字符串的情况

    算法关键及独到之处

    算法关键
    1、将前缀x!,姓名,手机号和地址的分开处理,同时删除最后的英文句号“.”。
    step1.通过“,”将字符串切割成x!+姓名和手机号+地址两部分

       				String level_name = str.split(",")[0];
       				String level = level_name.split("[!]")[0];
    

    step2.通过“!”分割前缀x和姓名

    				String name = level_name.split("[!]")[1];
    				String phone_address = str.split(",")[1];
    

    step3.通过创建匹配器的方式分割手机号和地址

    				Pattern pattern = Pattern.compile("((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}");
    				//创建匹配给定输入与此模式的匹配器。
    				Matcher matcher = pattern.matcher(phone_address);
    				while(matcher.find()) {
    				sb2.append(matcher.group());				}
    				String phone = sb2.toString();
    				String address = phone_address.replaceAll(phone, "");
    

    step4.用replaceAll删除“.”

    				address = address.replaceAll("[.]","");
    

    2、用getProvince方法处理省级或者市级的级别后缀缺失的情况。
    我的方法很简单,总而言之就是用了if---else语句:
    判断判断是否有“省” :if(!address.matches(".*省.*")){}
    有则进入之后的利用前缀x判断进行什么级别的地址划分,
    没有则接着判断是否有“市”:if(address.matches(".*市.*")) {}
    没有则接着判断第三级地址else if(address.matches(".*(区|县).*")){}
    将缺失的级别后缀补全,结束后返回xx省xx市+后面的详细地址。

    3、根据前缀x判断进行五级地址分割还是七级地址分割,通过getMatchesAddress方法进行五级地址分割,通过getMatchesAddressSeven进行七级地址分割。
      五级和七级的分割道理其实是差不多的,就是利用正则表达式逐级分割,我的方法还是很简单,简单来说就是把每一级的不同情况列举出来,所以碰到比较不规则的地址的时候可能会出错。我就拿七级地址分割来说,找出每一级地址的不同情况,比较不一样的是省级,还需要判断是否是直辖市。

    • 省级:
    			if(address.matches(".*(省|自治区|行政区).*")) {
    			int index = address.indexOf("省");	
    			int index2 = address.indexOf("自治区");	
    			int index3 = address.indexOf("行政区");	
    			if(index > -1) {
    				pr = address.substring(0,index+1);
    				temp = temp.substring(index+1);
    			}
    			if(index2 > -1) {
    				pr = address.substring(0,index2+3);
    				temp = temp.substring(index2+3);
    			}
    			if(index3 > -1) 
    			{
    				pr = address.substring(0,index3+3);
    				temp = temp.substring(index3+3);
    			}
    			if(pr.matches(".*北京.*")) {
    				pr = "北京";
    				temp = address.substring(index+1);
    			}
    			
    			if(pr.matches(".*上海.*")) {
    				pr = "上海";
    				temp = address.substring(index+1);
    			}
    			
    			if(pr.matches(".*天津.*")) {
    				pr = "天津";
    				temp = address.substring(index+1);
    			}
    			if(pr.matches(".*重庆.*")) {
    				pr = "重庆";
    				temp = address.substring(index+1);
    			}				
    		}
    
    • 市级:
    		if(temp.matches(".*市.*")) {
    			int index = temp.indexOf("市");
    			if(temp.matches(".*北京.*|.*上海.*|.*天津.*|.*重庆.*"))
    			{
    				city = temp.substring(0,index+1);
    			}
    			else{
    				city = temp.substring(0,index+1).replace(pr,"").trim();
    			}
    			temp = temp.substring(index+1);
    		}
    

    剩余的五个级别同理:

    • 第三级:if(temp.matches(".*(区|县|市|海域|岛|旗).*")) {}
    • 第四级:if(temp.matches(".*(街道|镇|乡).*")) {}
    • 第五级:if(temp.matches(".*(路|巷|道|街|弄|胡同).*")) {}
    • 第六级:if(temp.matches(".*号.*")) {}
    • 第七级:else {village = temp;}

    4、最后用getJson方法输出。

    独到之处
      嗯,我的方法真的很简单,毕竟只是个速成品,把地址单独分割出来后,利用正则表达式分割详细地址,在每一级中不停地判断和列举,并没有什么特别的地方。但是能解决一定问题的方法就是好方法嘛,对于我来说能有输出已经是一件很快乐的事情了。非要厚脸皮地说有什么独到之处的话,简单粗暴算嘛,勉强算吧,嘻嘻。(给点面子

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

    (1)改进时间

      这个真的花了蛮多时间的,至少三个小时,甚至更多,首先是因为没有看清楚代码需求,不知道要分级,也不知道不同级别对应不同的情况,还有就是没有考虑到不同级别的不同情况,一开始只考虑省市区县这样简单的几种情况,后来发现还有其他比较少见的一些情况,比如自治区、特别行政区之类的。

    (2)改进思路

    • 分级:把前缀分割出来后,利用前缀进行划分,同时设置两种方法,分别用于五级地址分割和七级地址分割。
    • 不同级别的不同情况:在我能想到和找到的情况范围内,在每个级别进行判断和列举。

    (3)性能分析图

    我使用的是Jprofiler进行性能分析

    消耗最大的方法是getMatchesAddress:

    public static ArrayList<String> getMatchesAddress (String address) {
    		String	pr = "";
    		String	city = "";
    		String	county = "";
    		String	town = "";
    		String	village = "";
    		String temp = address;
    		if(address.matches(".*(省|自治区|行政区).*")) {
    			int index = address.indexOf("省");	
    			int index2 = address.indexOf("自治区");	
    			int index3 = address.indexOf("行政区");	
    			if(index > -1) {
    				pr = address.substring(0,index+1);
    				temp = temp.substring(index+1);
    			}
    			if(index2 > -1) {
    				pr = address.substring(0,index2+3);
    				temp = temp.substring(index2+3);
    			}
    			if(index3 > -1) 
    			{
    				pr = address.substring(0,index3+3);
    				temp = temp.substring(index3+3);
    			}
    			if(pr.matches(".*北京.*")) {
    				pr = "北京";
    				temp = address.substring(index+1);
    			}
    			
    			if(pr.matches(".*上海.*")) {
    				pr = "上海";
    				temp = address.substring(index+1);
    			}		
    			if(pr.matches(".*天津.*")) {
    				pr = "天津";
    				temp = address.substring(index+1);
    			}	
    			if(pr.matches(".*重庆.*")) {
    				pr = "重庆";
    				temp = address.substring(index+1);
    			}	
    		}
    		if(temp.matches(".*市.*")) {
    			int index = temp.indexOf("市");
    			if(temp.matches(".*北京.*|.*上海.*|.*天津.*|.*重庆.*"))
    			{
    				city = temp.substring(0,index+1);
    			}
    			else{
    				city = temp.substring(0,index+1).replace(pr,"").trim();
    			}
    			temp = temp.substring(index+1);
    		}
    		if(temp.matches(".*(区|县|市|海域|岛|旗).*")) {
    			int index = temp.indexOf("区");
    			int index2 = temp.indexOf("县");
    			int index3 = temp.indexOf("市");
    			int index4 = temp.indexOf("海域");
    			int index5 = temp.indexOf("岛");
    			int index6 = temp.indexOf("旗");
    			if(index > -1) {
    				county = temp.substring(0,index+1).replace(city, "").trim();
    				temp = temp.substring(index+1);
    			}
    			if(index2 > -1) {
    				county = temp.substring(0,index2+1).replace(city, "").trim();
    				temp = temp.substring(index2+1);
    			}
    			if(index3 > -1) {
    				county = temp.substring(0,index3+1).replace(city, "").trim();
    				temp = temp.substring(index3+1);
    			}
    			if(index4 > -1) {
    				county = temp.substring(0,index4+2).replace(city, "").trim();
    				temp = temp.substring(index4+2);
    			}
    			if(index5 > -1) {
    				county = temp.substring(0,index5+1).replace(city, "").trim();
    				temp = temp.substring(index5+1);
    			}
    			if(index6 > -1) {
    				county = temp.substring(0,index6+1).replace(city, "").trim();
    				temp = temp.substring(index6+1);
    			}
    		}
    		if(temp.matches(".*(街道|镇|乡).*")) {
    			int index = temp.indexOf("街道");
    			int index2 = temp.indexOf("镇");
    			int index3 = temp.indexOf("乡");
    			if(index > -1) {
    				town = temp.substring(0,index+1).replace(county, "").trim();
    				village = temp.substring(index+1);
    			}
    			if(index2 > -1) {
    				town = temp.substring(0,index2+1).replace(county, "").trim();;
    				village = temp.substring(index2+1);
    			}
    			if(index3 > -1) {
    				town = temp.substring(0,index3+1).replace(county, "").trim();
    				village = temp.substring(index3+1);
    			}
    		}else {
    			village = temp;
    		}
    		ArrayList<String> arrayList = new ArrayList<String>();
    		arrayList.add(pr);
    		arrayList.add(city);
    		arrayList.add(county);
    		arrayList.add(town);
    		arrayList.add(village);
    		return arrayList;
    	}
    

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

    (1)单元测试代码

    public class test2 {
    	public static void main(String[] args) {
    		String[] arr = {"山西省太原市小店区鼓西街道湖滨路119号湖滨大厦一层",
    						"广西壮族自治区南宁市江南区白沙大道20号",
    						"新疆维吾尔自治区乌鲁木齐市乌鲁木齐县万盛大街4706号",
    						"湖南省长沙市天心区芙蓉中路二段116-1众东国际104室",
    						"福建省厦门市集美区理工南路852号厦门工艺美术学院4#205",
    						"四川省成都市武侯区人民南路四段20号叶婆婆钵钵鸡",
    						"福建省泉州市丰泽区丰泽街道丰迎路15号",
    						"福建省泉州市鲤城区庄府巷107号",
    						"湖南省长沙市天心区裕南街85号盟重烧烤",
    						"云南省水富县云川路1号水富火车站货运大楼",
    		for (int a = 0; a < arr.length; a++) {
    			Object[] array = getProvince(arr[a]).toArray();
    			for (int i = 0; i < array.length; i++) {
    				System.out.println(array[i]);}
    			System.out.println("---------------------------------------------");}}
    		public static ArrayList<String> getMatchesAddressSeven (String address) {
    		String	pr = "";
    		String	city = "";
    		String	county = "";
    		String	town = "";
    		String	path = "";
    		String	mark = "";
    		String	village = "";
    		String temp = address;
    		if(address.matches(".*(省|自治区|行政区).*")) {
    			int index = address.indexOf("省");	
    			int index2 = address.indexOf("自治区");	
    			int index3 = address.indexOf("行政区");	
    			if(index > -1) {
    				pr = address.substring(0,index+1);
    				temp = temp.substring(index+1);
    			}
    			if(index2 > -1) {
    				pr = address.substring(0,index2+3);
    				temp = temp.substring(index2+3);
    			}
    			if(index3 > -1) 
    			{
    				pr = address.substring(0,index3+3);
    				temp = temp.substring(index3+3);
    			}
    			if(pr.matches(".*北京.*")) {
    				pr = "北京";
    				temp = address.substring(index+1);
    			}
    			
    			if(pr.matches(".*上海.*")) {
    				pr = "上海";
    				temp = address.substring(index+1);
    			}
    			
    			if(pr.matches(".*天津.*")) {
    				pr = "天津";
    				temp = address.substring(index+1);
    			}
    			if(pr.matches(".*重庆.*")) {
    				pr = "重庆";
    				temp = address.substring(index+1);
    			}						
    		}
    		if(temp.matches(".*市.*")) {
    			int index = temp.indexOf("市");
    			if(temp.matches(".*北京.*|.*上海.*|.*天津.*|.*重庆.*"))
    			{
    				city = temp.substring(0,index+1);
    			}
    			else{
    				city = temp.substring(0,index+1).replace(pr,"").trim();
    			}
    			temp = temp.substring(index+1);
    		}
    		if(temp.matches(".*(区|县|市|海域|岛|旗).*")) {
    			int index = temp.indexOf("区");
    			int index2 = temp.indexOf("县");
    			int index3 = temp.indexOf("市");
    			int index4 = temp.indexOf("海域");
    			int index5 = temp.indexOf("岛");
    			int index6 = temp.indexOf("旗岛");
    			if(index > -1) {
    				county = temp.substring(0,index+1).replace(city, "").trim();
    				temp = temp.substring(index+1);
    			}
    			if(index2 > -1) {
    				county = temp.substring(0,index2+1).replace(city, "").trim();
    				temp = temp.substring(index2+1);
    			}
    			if(index3 > -1) {
    				county = temp.substring(0,index3+1).replace(city, "").trim();
    				temp = temp.substring(index3+1);
    			}
    			if(index4 > -1) {
    				county = temp.substring(0,index4+2).replace(city, "").trim();
    				temp = temp.substring(index4+2);
    			}
    			if(index5 > -1) {
    				county = temp.substring(0,index5+1).replace(city, "").trim();
    				temp = temp.substring(index5+1);
    			}
    			if(index6 > -1) {
    				county = temp.substring(0,index6+1).replace(city, "").trim();
    				temp = temp.substring(index6+1);
    			}
    		}
    		if(temp.matches(".*(街道|镇|乡).*")) {
    			int index = temp.indexOf("街道");
    			int index2 = temp.indexOf("镇");
    			int index3 = temp.indexOf("乡");
    			if(index > -1) {
    				town = temp.substring(0,index+2).replace(county, "").trim();
    				temp = temp.substring(index+2);
    			}
    			if(index2 > -1) {
    				town = temp.substring(0,index2+1).replace(county, "").trim();;
    				temp = temp.substring(index2+1);
    			}
    			if(index3 > -1) {
    				town = temp.substring(0,index3+1).replace(county, "").trim();
    				temp = temp.substring(index3+1);
    			}
    		}
    		if(temp.matches(".*(路|巷|道|街|弄|胡同).*")) {
    			int index = temp.indexOf("路");
    			int index2 = temp.indexOf("巷");
    			int index3 = temp.indexOf("道");
    			int index4 = temp.indexOf("街");
    			int index5 = temp.indexOf("弄");
    			int index6 = temp.indexOf("胡同");
    			if(index > -1) {
    			path = temp.substring(0,index+1).replace(town, "").trim();
    			temp = temp.substring(index+1);}
    			if(index2 > -1) {
    				path = temp.substring(0,index2+1).replace(town, "").trim();
    				temp = temp.substring(index2+1);}
    			if(index3 > -1) {
    				path = temp.substring(0,index3+1).replace(town, "").trim();
    				temp = temp.substring(index3+1);}
    			if(index4 > -1) {
    				path = temp.substring(0,index4+1).replace(town, "").trim();
    				temp = temp.substring(index4+1);}
    			if(index5 > -1) {
    				path = temp.substring(0,index5+1).replace(town, "").trim();
    				temp = temp.substring(index5+1);}
    			if(index6 > -1) {
    				path = temp.substring(0,index6+2).replace(town, "").trim();
    				temp = temp.substring(index6+2);}
    		}
    		
    		if(temp.matches(".*号.*")) {
    			int index = temp.indexOf("号");
    			mark = temp.substring(0,index+1).replace(path, "").trim();
    			village = temp.substring(index+1);
    		}
    		else {
    			village = temp;
    		}
    		ArrayList<String> arrayList = new ArrayList<String>();
    		arrayList.add(pr);
    		arrayList.add(city);
    		arrayList.add(county);
    		arrayList.add(town);
    		arrayList.add(path);
    		arrayList.add(mark);
    		arrayList.add(village);
    		return arrayList;
    	}
    
    

    测试答案为:

    山西省
    太原市
    小店区
    鼓西街道
    湖滨路
    119号
    湖滨大厦一层
    
    ---------------------------------------------
    广西壮族自治区
    南宁市
    江南区
    
    白沙大道
    20号
    
    
    ---------------------------------------------
    新疆维吾尔自治区
    乌鲁木齐市
    乌鲁木齐县
    
    万盛大街
    4706号
    
    
    ---------------------------------------------
    湖南省
    长沙市
    天心区
    
    芙蓉中路
    
    二段116-1众东国际104室
    
    ---------------------------------------------
    福建省
    厦门市
    集美区
    
    理工南路
    852号
    厦门工艺美术学院4#205
    
    ---------------------------------------------
    四川省
    成都市
    武侯区
    
    人民南路
    四段20号
    叶婆婆钵钵鸡
    
    ---------------------------------------------
    福建省
    泉州市
    丰泽区
    丰泽街道
    丰迎路
    15号
    
    
    ---------------------------------------------
    福建省
    泉州市
    鲤城区
    
    庄府巷
    107号
    
    
    ---------------------------------------------
    湖南省
    长沙市
    天心区
    
    裕南街
    85号
    盟重烧烤
    
    ---------------------------------------------
    云南省
    
    水富县
    
    云川路
    1号
    水富火车站货运大楼
    
    ---------------------------------------------
    
    

    (2)测试的函数

    测试的函数是getMatchesAddressSeven,已经在(1)中展示

    (3)构造测试数据的思路

    构造测试数据来源主要有三种:
    1、选择了一些比较奇怪的名字,比如自治区、巷、街之类的。
    2、从百度地图上随手点了一个位置。
    3、选择了一些我去过的地方。

    (4)测试覆盖率图

    主方法的覆盖率:

    测试方法的覆盖率:

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

    (1)在输入的省级是xxx自治区xx市,且省级和市级后缀都缺失的情况下,会出现补全错误和信息缺失的现象。
    输入:2!小王,广西壮族15822153326南宁江南区白沙大道20号.
    输出:{"姓名":"小王","手机":"15822153326","地址":["广西省","族市","宁江南区","","白沙大道","20号",""]}
    (2)针对上面那种情况我想试试看如果把市级后缀加上是否会出现缺失,虽然不出现缺失了,但是把省市混淆在一起了。
    输入:2!小王,广西壮族15822153326南宁市江南区白沙大道20号.
    输出:{"姓名":"小王","手机":"15822153326","地址":["广西壮族南宁省","广西壮族南宁市","江南区","","白沙大道","20号",""]}
    (3)还有一些奇怪的地址也会出现异常,比如字符串中出现连续的两个“市”,输出会出现缺失。
    输入:1!佘减觉,山东省枣庄市市中区13878001733大郭庄村216号大郭庄幼儿园.
    输出:{"姓名":"佘减觉","手机":"13878001733","地址":["山东省","枣庄市","大","","郭庄村216号大郭庄幼儿园"]}

    七、在PSP表格记录实际花费的时间

    八、小结

      说实话,从无到有的过程真是太坎坷了,现在凌晨三点,我啃了一个月饼续命。对于我来说主要的困难在主要于:
      (1)对于需求分析不够透彻,走了很多弯路,带来了很多不必要的麻烦。
      (2)学习一门新的语言Java。
      (3)熟悉并掌握一些完全陌生的软件,比如eclpise,jProfiler,并且利用它们去进行程序的测试、分析。
      (4)Github的上传,这太难了,难中难,困扰了我好久,我到现在都不知道我的程序能不能测评。
      每天熬到两三点,我只觉得涂到脸上的精华都给这几天熬夜熬没了。但是苦尽甘来,收获还是蛮多的:
      (1)大致了解了如何去规划完成一个程序的时间和步骤,以后
      (2)做一件事情之前一定要看清需求,分析清楚怎么做以后,再着手去做。
      (3)Java算是入了个门,也浅浅地掌握了正则表达式。
      (4)对于eclipse和jProfiler也有了一定程度的熟悉度。
      (5)大概了解了如何进行单元测试和性能分析。
      有种开学胜期末的感觉, 累但是它值得。

  • 相关阅读:
    leetcode 347. Top K Frequent Elements
    581. Shortest Unsorted Continuous Subarray
    leetcode 3. Longest Substring Without Repeating Characters
    leetcode 217. Contains Duplicate、219. Contains Duplicate II、220. Contains Duplicate、287. Find the Duplicate Number 、442. Find All Duplicates in an Array 、448. Find All Numbers Disappeared in an Array
    leetcode 461. Hamming Distance
    leetcode 19. Remove Nth Node From End of List
    leetcode 100. Same Tree、101. Symmetric Tree
    leetcode 171. Excel Sheet Column Number
    leetcode 242. Valid Anagram
    leetcode 326. Power of Three
  • 原文地址:https://www.cnblogs.com/cathyccathy/p/11521360.html
Copyright © 2011-2022 走看看