github
1.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
·Planning | · 计划 | 90 | 60 |
· Estimate | · 估计这个任务需要多少时间 | 1640 | 2025 |
·Development | · 开发 | 600 | 450 |
· Analysis | · 需求分析 (包括学习新技术) | 150 | 160 |
· Design Spec | · 生成设计文档 | 60 | 60 |
· Design Review | · 设计复审 | 45 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 45 |
· Design | · 具体设计 | 150 | 200 |
· Coding | · 具体编码 | 600 | 750 |
· Code Review | · 代码复审 | 60 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 30 | 45 |
·Reporting | · 报告 | 45 | 60 |
· Test Repor | · 测试报告 | 20 | 30 |
· Size Measurement | · 计算工作量 | 20 | 30 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 40 | 45 |
· 合计 | 1640 | 2025 |
2.解题思路
①符号分隔姓名;
②给定地址簿中数据里有手机号混进地址中,所以先提出手机号,然后删掉手机号,剩下混合地址;
③分级解析地址。
注:(1)提取手机号码正则表达式:
(?:((13[0-9]{1})|(15[0-9]{1})|(18[0,5-9]{1}))+\\d{8})
- 参考博客:https://blog.csdn.net/chaoyu168/article/details/51861095
(2)解析地址重点代码:
String regex="(?<province>[^省]+自治区|.*?省|.*?行政区|.*?市)(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市|.*?县)(?<county>[^县]+县|.+区|.+市|.+旗|.+海域|.+岛)?(?<town>[^区]+区|.+镇)?(?<village>.*)";
- 参考博客:https://blog.csdn.net/superSubfn/article/details/80290491
- https://blog.csdn.net/renfng/article/details/94738164
3.输入输出范例
- 输入范例:
- 输出范例:
4.设计与实现过程
主要函数名 | 实现功能 |
readToString() | 读取文件 |
writeToFile() | 写入文件 |
checkCellphone() | 提取手机号 |
CheckIfIsPhoneNumber() | 获得电话号码的正则表达式 |
deletephonenumber() | 删除手机号 |
isExistProvince() | 判断是否包含省级地区 |
restructure() | 处理没有指定省市后缀的地址 |
Map<String,String> addressResolution() | 通过正则表达式,将地址进行分割 |
Map<String,String> addressResolution() | 重构一次地址,将直辖市所在区域进行特殊处理 |
Map<String, String> addressFormat() | 格式化省市县/区信息 |
UserInfo() | 写入姓名 |
5.算法关键
- 按行读取文件,通过“,”分隔提取姓名信息,删除无效符号;
- 从字符串中提取手机号存入后删除手机号以方便后续解析地址;
- 解析地址,关键在于地址的分级解析,以及特殊形式地址的例子。
6.性能分析及代码覆盖率
7.代码说明
private static void writeToFile(String content) {
try {
//定义文件路径,没有该文件会自动创建,如果路径有文件夹,一定要有,不会自动创建文件夹
String filename = "src/outJson.txt";
File file = new File(filename);
if (!file.exists()) {
file.createNewFile();
}
byte[] b = content.getBytes(); //将字符串转换成字节数
OutputStream out = null;
try {
out = new FileOutputStream(file); //实例化OutpurStream
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//写入
out.write(b); //写入
out.close(); //关闭
} catch (Exception e) {
e.printStackTrace();
}
}
public static String checkCellphone(String str) {
String phone = "";
// 将给定的正则表达式编译到模式中
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(str);
//查找字符串中是否有符合的子字符串
while (matcher.find()) {
//查找到符合的即输出
// System.out.println("查询到一个符合的手机号码:" + matcher.group());
phone = matcher.group();
}
return phone;
}
public static List<Map<String, String>> addressResolution(String address) {
String regex = "(?<province>[^省]+自治区|.*?省|.*?行政区|.*?市)(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市|.*?县)(?<county>[^县]+县|.+区|.+市|.+旗|.+海域|.+岛)?(?<town>[^区]+区|.+镇)?(?<village>.*)";
Matcher m = Pattern.compile(regex).matcher(address);
String province = null, city = null, county = null, town = null, village = null;
List<Map<String, String>> table = new ArrayList<Map<String, String>>();
Map<String, String> row = null;
while (m.find()) {
row = new LinkedHashMap<String, String>();
province = m.group("province");
row.put("province", province == null ? "" : province.trim());
city = m.group("city");
row.put("city", city == null ? "" : city.trim());
county = m.group("county");
row.put("county", county == null ? "" : county.trim());
town = m.group("town");
row.put("town", town == null ? "" : town.trim());
village = m.group("village");
row.put("village", village == null ? "" : village.trim());
table.add(row);
}
return table;
}
8.心路历程与收获
用java解决该问题对我来说还是十分复杂的,其中不仅是姓名,手机号和地址的分别解析,还有输入输出文件的要求,这对对于java使用还十分不熟练的新手来说,每个问题的解决都要通过不停的查阅资料和更改代码,也更加突出了对于无法解决自己水平之外问题的难过,这说明计算机学习的两年生活中我对于计算机技能的掌握太不熟练,实在泰难了。在这之中,意识到了自己的不足之后,以后应该要用更多的时间充实自己,锻炼思考,多多学习java或者python等高级语言,学会靠自己的努力进取实现编程,在遇到下一次更难更复杂的问题时不再是一头雾水,而是有自己的一套逻辑思路,计算好编程开发的时间,失败乃成功之母,这次的困境是为了下次,希望下次有所进步。
9.异常处理说明
地址分级处理时,缺少省,市等的特殊地址形式无法解析。