总结性Blog
一,前言
这3次的作业中的知识点、题量、难度等情况如下:
首先在习题集04中主要考察了正则表达式的应用和继承的实现,只有三道题,题量不大。其中7-1 水文数据校验及处理对正则表达式的应用提出了较高的要求,题目难度较大(至少对我这类对正则表达式基本不清楚同时有对学习正则表达式有一定畏难和抵触情绪的人来说是这样的),这道题总共50分,在勉强挣扎的情况下,在“输入为连续多个空”这个点上通过,因此总共只得了两分,失分相当严重;7-2 日期问题面向对象设计(聚合一)这道题对以往日期题进一步改进,要求实现年月日与日期类之间的继承关系,题目难度不大,该题35分,全部测试点通过;7-3 图形继承 是最典型的继承书写题,充分展现了继承的书写过程,方法及继承的作用和特点,此题在3道题中相对简单,该题15分,全部测试点通过。
其次在题目集05中,共5道题,题量适中。7-1 找出最长的单词-hebust对字符串进行了考察,尤其对.split和.length两个String类中自定义的方法的理解和应用提出了要求,题目本身并不难,该题5分,全部测试点通过;7-2 合并两个有序数组为新的有序数组在之前的习题中有出现过,于是如法炮制,先将两个数组合并到一个新建的数组中,再对新建数组中的元素进行排序即可,相当简单,该题15分,全部测试点通过;7-3 对整型数据排序就是专门考察三种排序的算法,冒泡和选择排序之前就很熟,插入排序网上现学一下也就会了,难度很低,该题15分,全部测试点通过;7-4 统计Java程序中关键词的出现次数又是对正则表达式的考察,难度很大,该题25分,部分测试点未通过,扣了7分;7-5 日期问题面向对象设计(聚合二)是题目集04中7-2 日期问题面向对象设计(聚合一)的改进,不知道是不是题目测试没设计好,我没有修改类之间的关系,仅仅修改了输出,该题40分,测试点全部通过;
最后在题目集06中,共6道题,题量较大。7-1 正则表达式训练-QQ号校验,7-2 字符串训练-字符排序,7-3 正则表达式训练-验证码校验,7-4 正则表达式训练-学号校验都是对正则表达式的一些最基础的考察,代码量很小,难度适中,所有题均通过测试点。7-5 图形继承与多态继续考察继承的同时又增添了多态的思想,对父类的方法进行重写是本题的重点,难度并不大,该题40分,全部测试点通过;7-6 实现图形接口及多态性主要还是考验学生接口的学习情况,并未和其他算法相结合,仅仅考察接口的情况下,使得这道题简单易行,该题30分,全部测试点通过。
二,设计与分析
①题目集4(7-2)、题目集5(7-4)两种日期类聚合设计的优劣比较
虽然题目集4(7-2)利用日期类和年月日的层层继承同样体现了子类继承父类的一些优势,但年月日类均继承于日期的方式,正如题目集5(7-4),将年月日类都归为日期的子类,层次清晰,最主要的是发挥了多态的优势。
以上是题目集5(7-4)的题目所给出的类图,通过类图我们不难发现,Day,Month,Year和DateUtil是继承关系,而Main依赖于DateUtil类,在这样的结构中,几乎所有的属性和方法都可以在DateUtil这个父类中完成,而作为子类的Day,Month,Year只需稍微添加一下自己特有的属性以及对父类的方法进行重写就可以了。
而在聚合一中Main依赖于DateUtil类,Day继承于DateUtil类,Month又继承于Day类,Year又继承于Month类,这样就是DateUtil的工作量分配到相继的子类中,同时子类要不断定义新的属性,如果其中某个中间类出现了问题就会产生连锁反应,从而带来不便。
②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
题目集4(7-3)是最基础的继承关系,即Circle,Rectangle,Ball,Box分别继承于Shape这一父类,而把各自的属性和方法封装在相应的类中;
以上类图展现了该继承关系(Shape主类与 父类重名);
题目集6(7-5)在题目集4(7-3)的基础上,子类除了重写父类的方法GetArea(),同时各自增加了独属于自己的方法
以上类图展现了子类丰富自身的过程;
题目集6(7-6)中建立了接口GetAreas,进而让Circle和Rectangle类去完善接口中的空方法,即实现了多态——让对象具有多种表现形式,面对不同的对象,有不同的求面积方法,大大提高了面向对象编程的灵活性和可扩充性,其类图如下:
③对三次题目集中用到的正则表达式技术的分析总结
7-1 水文数据校验及处理 中通过
private boolean validateMeasureDateTime(String measureDateTime) {
String eL = "((([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})"
+ "/((([13578]|1[02])/([1-9]|[12][0-9]|3[01]))|(([469]|11)/([1-9]|[12][0-9]|30))|"
+ "(2-([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|"
+ "[2468][048]|[3579][26])00))/02/29)|(([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})/((([13578]|1[02])/([1-9]|[12][0-9]|3[01]))|(([469]|11)/"
+ "([1-9]|[12][0-9]|30))|(2/([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})([48]|[2468][048]|"
+ "[13579][26])|(([48]|[2468][048]|[3579][26])00))/02/29)) (([02468]|([1][02468])|([2][02])):00)";
实现对输入字符串根据"/"," ","|",以及对应字符的成分(数字,字母,符号)和长度进行分割数据;
7-4 统计Java程序中关键词的出现次数 中通过
for(int i=0;;i++) {
a=input.nextLine();
if(a.equals("exit"))
break;
if(a.matches("(.*)//(.*)"))
{String b[]=a.split("//");
ss.append(b[0]+" ");
//ss.append('\n');
}
else
{ss.append(a+" ");
//ss.append('\n');
}
}
int count=0;
String s=ss.toString();
// System.out.println(s);
Pattern p=Pattern.compile("\"(.*?)\"");
Matcher m=p.matcher(s);
while(m.find()){
s=s.replace(m.group()," ");
p=Pattern.compile("\"(.*?)\"");
m=p.matcher(s);
}
p=Pattern.compile("/\\**(.*?)/");
m=p.matcher(s);
while(m.find()){
s=s.replace(m.group()," ");
// p=Pattern.compile("/\\*(.*?)\\*/");
m=p.matcher(s);
}
// System.out.println(s);
if(s.isEmpty())
{System.out.println("Wrong Format");
System.exit(0);
}
s=s.replace("["," ");
s=s.replace("]"," ");
s=s.replace("-","a");
s=s.replace("*","a");
s=s.replace("/","a");
s=s.replace("+","a");
s=s.replace(">","a");
s=s.replace("=","a");
s=s.replace("!","a");
s=s.replace(":","a");
s=s.replace("\\","a");
s= s.replaceAll("[^a-zA-Z]", " ");
String []s1=s.split("[ ' ']");
通过与关键词数组中的关键词库进行逐一比对,将无关的字符,空格,字母等进行转化,从而找到关键词并计数;
7-1 正则表达式训练-QQ号校验通过
String regex="[1-9][0-9]{4,14}";
boolean findit=qq.matches(regex);
将输入字符串进行
- 要求必须是 5-15 位;
- 0 不能开头;
- 必须都是数字
条件约束下 的匹配和判断;
7-3 正则表达式训练-验证码校验 通过
String regex="([a-z]|[A-Z]|[0-9]){4}";
boolean findit=yanzheng.matches(regex);
实现满足"验证码是由四位数字或者字母(包含大小写)组成的字符串"条件下的匹配和判断;
7-4 正则表达式训练-学号校验通过
Pattern p=Pattern.compile("2020(1[1-7]|61|7[1-3]|8[12])(0[1-9]|[1-3][0-9]|40)");
Matcher m=p.matcher(number);
实现满足“1学号共8位;2第1,2位是20;3第3,4为取值在11-17,61,71-73,81,82之间;4每个班级学号后两位为01~40”条件下的匹配和判断;
④题目集5(7-4)中Java集合框架应用的分析总结
1.所有集合类都位于java.util包下。Java的集合类主要由两个接口派生而出:HashMap和Map,HashMap和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。
2.Map实现类用于保存具有映射关系的数据(key-value)。Set、List和Map可以看做集合的三大类。
3.对于Set、List和Map三种集合,最常用的实现类分别是HashSet、ArrayList和HashMap三个实现类。
三,采坑心得:
有时候就是会一道题敲个一上午或一下午,也是在充分理解题意的情况下,希望仅凭现有的所学知识解决问题,其实很多时候遇到的问题可以分为两大类,第一我知道是题目要考察什么,但是具体到某个知识点或者算法我不是很熟悉,这个时候就要及时的翻阅教材和查阅如菜鸟教程和诸多的博客经验去弥补自己的知识理解的不足;第二,如果我甚至没弄明白题目考察点,这个时候,就算我想破脑瓜,翻破书本也无济于事,因为这时的我就像个无头苍蝇乱飞,注定所作出的努力都将白费,解决此类问题的最好的办法就是搜题,搜原题,瞄一眼博主写的正确答案,看下他的代码里是否真的用到我完全没接触过的东西,如果有,那么就有了方向,进行针对性的学习;如此一来,我的解题效率便大大提升。
如在题目集05中的找关键词一题,我就完全不会,结果搜到答案中出现
import java.util.Set;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
和
Set set=map.keySet();
Object[] arr=set.toArray();
Arrays.sort(arr);
for(Object k:arr){
System.out.println(map.get(k)+"\t"+k);
这些极陌生的字段告诉我,这道题“超纲了”,于是我开始针对Set,Map等关键词进行深度的搜索,学习,从而有了更深一步的了解。
对于题目集05的7-3 对整型数据排序 这道题,我就清楚的知道题目要考察我的是什么,接着要做的就是复习冒泡排序(不是很清楚,有些细节忘记了)以及学习什么是插入排序,它的算法过程是怎样的,按照这样的流程,问题自然迎刃而解。
四,改进建议
对于7-4 统计Java程序中关键词的出现次数这道题原编译结果如下图
if(s.isEmpty())
{System.out.println("Wrong Format");
System.exit(0);
}
s=s.replace("["," ");
s=s.replace("]"," ");
s=s.replace("-","a");
s=s.replace("*","a");
s=s.replace("/","a");
s=s.replace("+","a");
s=s.replace(">","a");
s=s.replace("=","a");
s=s.replace("!","a");
s=s.replace(":","a");
s=s.replace("\\","a");
s= s.replaceAll("[^a-zA-Z]", " ");
在原代码中使用以上替换思想应该就能通过剩下的测试点;
7-1 水文数据校验及处理最大的问题还是正则的匹配式出了问题,参照老师给出的答案中的匹配式
private boolean validateMeasureDateTime(String measureDateTime) {
String eL = "((([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})"
+ "/((([13578]|1[02])/([1-9]|[12][0-9]|3[01]))|(([469]|11)/([1-9]|[12][0-9]|30))|"
+ "(2-([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|"
+ "[2468][048]|[3579][26])00))/02/29)|(([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})/((([13578]|1[02])/([1-9]|[12][0-9]|3[01]))|(([469]|11)/"
+ "([1-9]|[12][0-9]|30))|(2/([1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})([48]|[2468][048]|"
+ "[13579][26])|(([48]|[2468][048]|[3579][26])00))/02/29)) (([02468]|([1][02468])|([2][02])):00)";
应该就可以实现改题目的功能;
五,总结
通过本阶段的习题,我逐渐意识到仅仅靠课堂上理解的那点东西是远远不够的,我只有通过加强向图书馆借阅Java编程相关的书籍以及在线Java教程的学习,和遇到问题时查找资料的这些能力,才能在今后的编程中得心应手;
然后以前不知道Java这门课是不考试的,所以作业上就没多在意,之前有很多题都还是可以多挣扎一下,多得点分的,现在意识到作业的重要性,自然从现在,以后都要在习题上肯下功夫,做到精益求精吧。