目录
1.前言
2.设计与分析
3.踩坑心得
4.改进建议
5.总结
一、前言
题目集4:
知识点:考察通过java编写功能实现方法和类、数据的输入与输出、处理字符串以及利用正则表达式对输入数据进行校检处理、大数数学运算、日期处理、继承的使用等等。
题量:较少
难度:较难,题目代码量大,7-2和7-3可通过前题目集代码扩展实现。
题目集5:
知识点:考察通过java编写功能实现方法和类、数据的输入与输出、字符串类方法的使用、数组的使用、数组的排序方法(插入排序、选择排序及冒泡排序)、接口的使用(List、Set或Map)、处理字符串以及利用正则表达式对输入数据进行校检处理、日期处理等等。
题量:较多
难度:适中,题目有难有易,7-5可通过前题目集代码优化实现。
题目集6:
知识点:考察通过java编写功能实现方法和类、数据的输入与输出、处理字符串以及利用正则表达式对输入数据进行校检处理、对数组进行排序、日期处理、继承、接口和多态的使用等等。(该题目集主要对训练正则表达式的使用)
题量:较多
难度:适中,题目代码量大,7-5可通过前题目集代码改进实现。
二、设计与分析
1.分析题目集4(7-2)、题目集5(7-5)两种日期类聚合设计的优劣之处:
题目:题目集4(7-2)
设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
- 1 year month day n //测试输入日期的下n天
- 2 year month day n //测试输入日期的前n天
- 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
- 当输入有误时,输出格式如下:
Wrong Format
- 当第一个数字为1且输入均有效,输出格式如下:
year-month-day
- 当第一个数字为2且输入均有效,输出格式如下:
year-month-day
- 当第一个数字为3且输入均有效,输出格式如下:
天数值
本题分析:本题类之间的关系紧密连接,DateUtil类中提供Day类、Day类中提供Month类、Month类中提供Year类,在程序编码时使用起来思路清晰(有点使用递归的感觉~),结构功能使用从大到小,适合在该代码上进行扩展功能,但作为编码者来说,使用起来代码略过冗杂,可以进一步使用继承和接口对其进行优化。
部分代码展示:
class Day{ int value=0; Month month = new Month();//<---(提供Month对象) public Day(){ } public Day(int yearValue,int monthValue,int dayValue){ this.value = dayValue; this.month.value = monthValue; this.month.year.value = yearValue; } } class Month{ int value=0; Year year = new Year();//<---(提供Year对象) public Month(){ } public Month(int yearValue,int monthValue){ this.year.value = yearValue; this.value = monthValue; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Year getYear() { return this.year; } public void setYear(Year year) { this.year = year; } } class Year{ int value=0; public Year(){ } public Year(int value){ this.value = value; } public int getValue() { return this.value; } public void setValue(int value) { this.value = value; } public void yearIncrement() { this.value ++; } public void yearReduction() { this.value --; } }
生成报表展示:(使用SourceMonitor)
类图展示:(使用PowerDesigner)
题目:题目集5(7-5)
设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
- 1 year month day n //测试输入日期的下n天
- 2 year month day n //测试输入日期的前n天
- 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
- 当输入有误时,输出格式如下:
Wrong Format
- 当第一个数字为1且输入均有效,输出格式如下:
year1-month1-day1 next n days is:year2-month2-day2
- 当第一个数字为2且输入均有效,输出格式如下:
year1-month1-day1 previous n days is:year2-month2-day2
- 当第一个数字为3且输入均有效,输出格式如下:
The days between year1-month1-day1 and year2-month2-day2 are:值
本题分析:本题将Year、Month、Day类都在DateUtil给出,使得程序结构功能紧密,适合
直接作为一个日期处理功能化类来被其他类所使用(对于自我来说,这种结构更加友好哈哈哈~)。
这道题就不展示代码了~~~
生成报表展示:(使用SourceMonitor)
类图展示:(使用PowerDesigner)
总结:首先,站在用户的角度来看待程序,两个程序都需要进行改进,没有提供吃功能说明,但第二个程序的输出更加对用户友好(haha~至少给出了部分说明),其次,从程序的方面说明,两种程序类结构不同,前者可拓展性强,后者更适合作为功能类被调用。
2.分析题目集4(7-2)和题目集6(7-5、7-6)三种渐进式图型继承设计思路与技术运用
题目:题目集4(7-2)
题目见上,略。
本题分析:封装性较差,未使用继承、多态与接口。
题目:题目集6(7-5)
掌握类的继承、多态性及其使用方法。
输入格式:
从键盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。
输出格式:
- 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出
Wrong Format
。 - 如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
- 各个图形的面积;
- 所有图形的面积总和;
- 排序后的各个图形面积;
- 再次所有图形的面积总和。
本题分析:封装性较好,使用了继承、多态,但未使用到接口,程序整体层次较为良好。
部分代码展示:
1 class Shape{ 2 3 public double getArea() { 4 return 0; 5 } 6 } 7 8 class Circle extends Shape{ 9 private double radius; 10 11 public Circle(double radius) 12 { 13 this.radius = radius; 14 } 15 public double getArea() { 16 return Math.PI * radius * radius; 17 } 18 } 19 20 class Rectangle extends Shape{ 21 private double width; 22 private double length; 23 24 public Rectangle(double width,double length) 25 { 26 this.length = length; 27 this.width = width; 28 } 29 public double getArea() { 30 return length * width; 31 } 32 } 33 34 class Triangle extends Shape{ 35 private double side1; 36 private double side2; 37 private double side3; 38 39 public Triangle(double side1,double side2,double side3) 40 { 41 this.side1 = side1; 42 this.side2 = side2; 43 this.side3 = side3; 44 } 45 public double getArea() { 46 double p=(side1+side2+side3)/2; 47 return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3)); 48 } 49 }
题目:题目集6(7-6)
编写程序,使用接口及类实现多态性,类图结构如下所示其中:
- GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法;
- Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口
- 要求:在Main类的主方法中分别定义一个圆类对象及矩形类对象(其属性值由键盘输入),使用接口的引用分别调用圆类对象及矩形类对象的求面积的方法,直接输出两个图形的面积值。(要求只保留两位小数)
输入格式:
从键盘分别输入圆的半径值及矩形的宽、长的值,用空格分开。
输出格式:
- 如果输入的圆的半径值及矩形的宽、长的值非法(≤0),则输出
Wrong Format
- 如果输入合法,则分别输出圆的面积和矩形的面积值(各占一行),保留两位小数。
本题分析:封装性较好,使用了接口,但未使用到继承、多态,程序整体层次较为良好
部分代码展示:
1 interface GetArea{ 2 public double getArea(); 3 } 4 5 class Circle implements GetArea{ 6 private double radius; 7 8 public Circle(){ 9 } 10 public Circle(double radius){ 11 this.radius = radius; 12 } 13 public double getArea() { 14 return Math.PI * radius * radius; 15 } 16 } 17 18 class Rectangle implements GetArea{ 19 private double width; 20 private double length; 21 22 this.length=length; 23 } 24 public Rectangle(){ 25 } 26 public Rectangle(double width,double length){ 27 this.length = length; 28 this.width = width; 29 } 30 public double getArea() { 31 return length * width; 32 } 33 }
总结:程序合理使用继承和接口,体现了java的多态,可以大大提升程序的功能的拓展性(所以以后可以多多去使用继承和接口哦,但要合理)。
3.分析三次题目集正则表达式的使用
让我们来看看别人对正则表达式的评价吧!
首先,正则表达式在几乎所有语言中都可以使用,无论是前端的JavaScript、还是后端的Java、c#。他们都提供相应的接口/函数支持正则表达式。
但很神奇的是:无论你大学选择哪一门计算机语言,都没有关于正则表达式的课程给你修,在你学会正则之前,你只能看着那些正则大师们,写了一串外星文似的字符串,替代了你用一大篇幅的if else代码来做一些内容校验。
以上摘自:https://juejin.im/post/5b96a8e2e51d450e6a2de115
足以体现正则表达式的功能强大之处!!!(好了,废话不多说,让我们来分析这三次的正则表达式的使用)
分析总结:首先题目集4(7-1 水文数据校验及处理)一上来就出王牌(对一行输入的数据的正确格式进行判断),本题及其考验大家对正则表达式的使用和理解,考察了许多正则表达式的功能使用方式——如元字符、重复限定符、分组、转义、条件或、区间等等(一题能顶3.4题~),再然后是题目集5(7-4 统计Java程序中关键词的出现次数),需要合理使用正则表达式对输入内容进行筛选捕获以及对输入内容的正确性进行判断(虽然现在我还是不明白我最后一个测试点错在哪了555),最后是题目集6,本题目集基本就是为了训练正则表达式的使用而创设(而且有种在写Acm题的感觉了~),题目整体不难,主要考察正则表达式的基本使用(查找匹配、校检、替换等等)。
4.分析题目集5(7-4)中集合框架的应用
题目:题目集5(7-4)
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
- Java*有53个关键字(自行百度)
- 从键盘输入一段源码,统计这段源码中出现的关键字的数量
- 注释中出现的关键字不用统计
- 字符串中出现的关键字不用统计
- 统计出的关键字及数量按照关键字升序进行排序输出
- 未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit
行作为结束标志
输出格式:
- 当未输入源码时,程序输出
Wrong Format
- 当没有统计数据时,输出为空
- 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为
数量\t关键字
分析总结:本题可参考思路——将输入的内容利用StringBuilder连接起来作为一个整体,再利用正则表达式对整体进行查找匹配、校检等操作。这里主要谈谈Java中所提供的集合框架(类似c++中stl),这里使用Map更加方便储存关键词出现次数,键用String类型,值用int类型。另外,在java中,集合框架是围绕一组标准接口而设计,提供了许多有用的接口、数据结构和算法等,功能十分强大,合理使用有利于提升对数据的功能实现的高效性。
部分代码展示:
1 String []key= { "abstract","assert","boolean","break","byte","case","catch", 2 "char","class","const","continue","default","do","double","else", 3 "enum","extends","false","final","finally","float", 4 "for","goto","if","implements","import","instanceof", 5 "int","interface","long","native","new","null","package", 6 "private","protected","public","return","short","static", 7 "strictfp","super","switch","synchronized","this","throw", 8 "throws","transient","true","try","void","volatile","while"}; 9 Map<String,Integer> map = new HashMap<String,Integer>(); 10 for(int i=0;i<53;i++) 11 map.put(key[i], 0); 12 StringBuilder s = new StringBuilder(); 13 String get_in = new String(); 14 String res1 = "//.*$";//整行注释 15 String res2 = "\"(.*)\"";//字符串 16 String res3 = "/\\**(.*)\\*/";//{/* */}型注释 17 String res4 = "\\s+";//多空格 18 int i; 19 for(i=0;true;i++) { 20 get_in=scanner.nextLine(); 21 if(i==0&&get_in.equals("exit")) 22 { 23 System.out.println("Wrong Format"); 24 System.exit(0); 25 } 26 if(get_in.equals("exit")) 27 break; 28 get_in=get_in.replaceAll(res1, " "); 29 get_in=get_in.replaceAll(res2, " "); 30 get_in=get_in.replaceAll(res3, " "); 31 s.append(get_in+' '); 32 } 33 String all = s.toString();
四.改进建议
1.养成好习惯,写代码需要加上必要的注释并保证代码编写的规范性。
2.充分利用java的封装性,隐藏对象的属性和实现细节,建立各个对象之间的松耦合关系,合理利用继承、接口和集合框架,有助于提升程序的扩展性、适应性。
3.编写方法时要多从对象去考虑,提高程序的简洁性、建立各个对象之间的松耦合关系
五.总结
通过这三次题目集的训练,使我进一步对java语言有了更深的理解,在保证编写代码的简洁性上,可以合理地利用继承和接口优化类之间地关系,特别是体现在本次题目集4-6中对程序功能的逐步扩展和优化。另外,通过本次题目集训练,加强巩固了我对正则表达式的理解。但自己对集合框架的使用并不清楚,存在许多不懂的地方,课后将继续深入学习,并按时回顾,进一步提升自己对java语言使用的能力!