第二次博客作业
1.前言
习题集总结
本月习题集知识点包括正则表达式的使用,聚合,继承,多态,接口。涵盖的内容很全面,说明老师出题认真,由简变难,
逐层增加难度。题集题量适中,有大题有小题,难度有难有易,适合巩固基础知识,拓展编程思维。
2.设计与分析
第四次题目集7-2与第五次题目集7-5两种聚合优劣比较
第四次题目集7-2题目情况
日期问题面向对象设计,应用程序共有三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
如下为题目要求的类图
第四次题目集7-2设计思路
按照题目的要求设计类,包括设计DateUtil,Year,Month,Day四个类和主类。在Month类中聚合Day类,在Year类中聚合Month类,在DateUtil类中聚合Year类,其中DateUtil为业务类,在主类中创建DateUtil类型,输入数据和调用不同方法实现不同的功能。其中调用不同方法使用switch(),先调用方法判断数据合法性,若不合法则输出“Wrong Format”,若合法则输出结果。
第四次题目集7-2源码分析
思路简单,层次清晰。在主类中定义,调用不同方法。
下图为第四次题目集7-2的源码分析报表。


第五次题目集7-5题目情况
与第四次题目集7-2题目要求相近,但类的设计要求不同。
第五次题目集7-5类图设计要求如下图

第五次题目集7-5源码分析

两种聚合比较比较
第四次题目集7-2的聚合也是组合,是关联关系的一种,是比聚合关系强的一种关系。我们在 A 类的构造方法中创建 B 类对象。这样当创建一个 A 类对象时,也会同时产生 B 类的对象;当 A 类的这个对象消亡时,它所包含的 B 类的对象也会随之消亡,所以说,这两个类的生命周期是一致的。
第五次题目集7-5的结构是聚合,A类的对象在创建时不会立即创建B类的对象,而是在 A 类的某个方法中设计一个参数,用于接收 B 类对象的数据。当定义 A 类的对象消亡时,它方法所接收的 B 类的对象没有受到影响,也就是说,这两个类的生命周期并不一致。
组合的耦合性比聚合的耦合性强,当一个类发生变化时,对其他类造成的影响程越小则耦合度越弱,影响越大则耦合度越强。关联是指类的关系,聚合是一种比较强的关联,而组合则是一种更强的关联,在实际应用中,我们当然希望代码的耦合性越小越好,因为降低耦合性会提高开发效率和保证软件质量的目的,从而达到复用的目的。
题目集4(7-3)与题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用
(封装、继承、多态、接口等)
第四次题目集7-3
题目集4(7-3)主要涉及的是类的封装与继承。其中Circle继承自Shape,类中所有属性均为私有,均由setter(),getter()方法实现写入与读取,体现了面对对象编程的封装和继承的特性。其中getArea()方法在子类中重写,体现出多态性。
部分代码如下图所示。
1 class Shape { 2 3 public Shape() { 4 super(); 5 System.out.println("Constructing Shape"); 6 // TODO Auto-generated constructor stub 7 } 8 9 public double getArea(){//求图形面积 10 return 0.0; 11 } 12 } 13 14 class Circle extends Shape{ 15 private double radius = 0; 16 17 public Circle(double radius) { 18 super(); 19 this.radius = radius; 20 System.out.println("Constructing Circle"); 21 } 22 23 24 public Circle() { 25 super(); 26 System.out.println("Constructing Circle"); 27 // TODO Auto-generated constructor stub 28 } 29 30 public double getRadius() { 31 return radius; 32 } 33 34 35 public void setRadius(double radius) { 36 this.radius = radius; 37 } 38 39 40 public double getArea(){//求图形面积 41 return Math.PI * this.radius * this.radius; 42 } 43 44 }
题目集4(7-3)的类关系图如下。

题目集4(7-3)的源码复杂度分析图如下。
第六次题目集7-5
该题与题目集4的7-3相比凸显出了多态性,相关代码如下。
1 ArrayList<Shape> list = new ArrayList<Shape>(); 2 for(int i = 0; i < (a + b + c); i ++ ) { 3 if( i < a) { 4 Circle circle = new Circle(); 5 zhi1 = input.nextDouble(); 6 circle.setRadius(zhi1); 7 list.add(circle); 8 }else if( i < a + b) { 9 Rectangle rectangle = new Rectangle(); 10 zhi1 = input.nextDouble(); 11 zhi2 = input.nextDouble(); 12 rectangle.setLength(zhi1); 13 rectangle.setWidth(zhi2); 14 list.add(rectangle); 15 }else { 16 Triangle triangle = new Triangle(); 17 zhi1 = input.nextDouble(); 18 zhi2 = input.nextDouble(); 19 zhi3 = input.nextDouble(); 20 triangle.setSide1(zhi1); 21 triangle.setSide2(zhi2); 22 triangle.setSide3(zhi3); 23 list.add(triangle); 24 } 25 }
创建一个Shape自定义类型链表后,改链表为空,在for语句循环中对链表添加不同类型的子类,在进行求面积时,均调用getArea()方法,在链表里的不同的对象,接受同一消息时产生不同操作,体现出了面对对象编程的多态性。
第六次题目集7-6
第六次题目集7-6使用接口,接口使用需要用到implements。implements是实现某个接口,implements后面接接口类,详细用法如下图。
1 interface GetArea { 2 public double getArea(); 3 4 } 5 6 class Circle implements GetArea { 7 private double radius; 8 9 public Circle() { 10 super(); 11 // TODO Auto-generated constructor stub 12 } 13 14 public Circle(double radius) { 15 super(); 16 this.radius = radius; 17 } 18 19 public double getRadius() { 20 return radius; 21 } 22 23 public void setRadius(double radius) { 24 this.radius = radius; 25 } 26 27 public double getArea() { 28 return Math.PI * radius * radius; 29 30 } 31 32 public String toString() { 33 String str = String.valueOf(getArea()); 34 return str; 35 } 36 }
对三次题目集中用到的正则表达式技术的分析总结
谈对正则的认识
一个正则表达式是一个用于文本搜索的文本模式,可以用正则表达式搜索文本中想要的信息,例如在网页中搜索邮箱地址,电话号码,在新闻中查找关键字。也可以用于检验信息的正确性,例如检验邮箱是否合法,QQ号是否正确,等等。正则表达式的使用使得文本处理更加简单,便捷,更加多样化。
Java中有关正则的一些方法
compile() 可用此方法得到一个Pattern 实例,例如
Pattern pattern = Pattern.compile("abc");
matcher() 用于匹配文本中的模式,例如
String str = "abc123";
Matcher matcher = pattern.matcher(str); // 即可对str进行匹配
matches()
返回值为boolean类型,该方法若查找到对象返回true,否则返回false。
matches() 方法不能用于查找正则表达式多次出现。
split()
返回一个数组。
可以用正则表达式作为分隔符,把文本分割为String类型的数组。
例如
String text = "A wonderful and valuable method"; // 每个单词之间均有一个空格 Pattern pattern = Pattern.compile(" "); // 以一个空格为分隔符 String[] shuzu = pattern.split(text); // shuzu为一个字符串数组
find()与group()
使用示例如下
1 PTA第四次题目集7-1部分代码 2 3 public String[] getData1() { 4 String[] string = this.data.split("\\|"); 5 6 Column1 = string[0]; 7 Column2 = string[1]; 8 Column3 = string[2]; 9 10 Pattern p = Pattern.compile("\\d{1,9}(\\.\\d{1,9})?"); 11 Matcher m = p.matcher(string[3]); 12 int i = 0; 13 while(m.find()) { // 此处使用了find() 14 switch(i) { 15 case 0: Column4 = m.group();i++;break; // 此处使用了group() 16 case 1: Column5 = m.group();break; 17 } 18 19 } 20 Column6 = string[4]; 21 22 return string; 23 }
Java正则在PTA中的使用实例
第六次题目集7-1完整代码
该题为正则表达式训练-QQ号校验
校验键盘输入的 QQ 号是否合格,判定合格的条件如下:
- 要求必须是 5-15 位;
- 0 不能开头;
- 必须都是数字;
输出要求:
- 如果合格,输出:“你输入的QQ号验证成功”;
- 否则,输出:“你输入的QQ号验证失败”。
1 import java.util.Scanner; 2 import java.util.regex.Matcher; 3 import java.util.regex.Pattern; 4 5 public class Main { 6 public static void main (String[] args) { 7 Scanner input = new Scanner(System.in); 8 String str = input.nextLine(); 9 Pattern p = Pattern.compile("^[^0]\\d{4,14}$"); 10 Matcher m = p.matcher(str); 11 boolean result = m.matches(); 12 if(result) { 13 System.out.print("你输入的QQ号验证成功"); 14 }else { 15 System.out.print("你输入的QQ号验证失败"); 16 } 17 } 18 }
第五次题目集7-4中Java集合框架应用的分析总结
题目情况
统计Java程序中关键词的出现次数
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
- Java中共有53个关键字(自行百度)
- 从键盘输入一段源码,统计这段源码中出现的关键字的数量
- 注释中出现的关键字不用统计
- 字符串中出现的关键字不用统计
- 统计出的关键字及数量按照关键字升序进行排序输出
- 未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit行作为结束标志
输出格式:
- 当未输入源码时,程序输出
Wrong Format - 当没有统计数据时,输出为空
- 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为
数量\t关键字
设计思路
1.使用StringBuilder输入数据,并将StringBuilder转化为String类型。
1 Scanner input=new Scanner(System.in); 2 StringBuilder sb = new StringBuilder(); 3 4 String s1 = "exit"; 5 String s2 = " "; 6 String ss = "\n"; 7 String str = input.nextLine(); 8 9 while(!(str.equals(s1))) { 10 sb.append(str); 11 sb.append(ss); 12 str = input.nextLine(); 13 14 } 15 16 String str1 = sb.toString();
2.从String类型的str1从提取有效信息并存于str2
有效信息是指没有被注释或者字符串包含的单词。
1 Pattern p = Pattern.compile("\\w+|\"|//|/\\*|\n|\\*/"); 2 Matcher m = p.matcher(str1); 3 int a = 0,b = 0; 4 int c = 1; 5 ArrayList<String> list = new ArrayList<String>(); 6 String sss = ""; 7 while(m.find()) { 8 9 sss = m.group(); 10 if(sss.equals("\"")) { 11 c = -1 * c; 12 continue; 13 } 14 if(sss.equals("//")) { 15 a = 1; 16 continue; 17 } 18 if(sss.equals("\n")) { 19 a = 0; 20 continue; 21 } 22 if(sss.equals("/*")) { 23 b = 1; 24 continue; 25 } 26 if(sss.equals("*/")) { 27 b = 0; 28 continue; 29 } 30 31 32 if(sss.equals("exit")) { 33 break; 34 } 35 if(a == 0 && b ==0 && c == 1) 36 list.add(sss); 37 } 38 39 StringBuilder sq = new StringBuilder(); 40 for(String temp: list) { 41 sq.append(temp); 42 sq.append(s2); 43 } 44 45 String str2 = sq.toString();
3.在str2中计算关键字的出现次数同时按格式输出结果
1 for(int i = 0; i < 53 ; i ++) { 2 Pattern p1 = Pattern.compile(KEYWORDS[i]); 3 Matcher m1 = p1.matcher(str2); 4 int j = 0; 5 while(m1.find()) { 6 m1.group(); 7 j ++; 8 } 9 System.out.println(j); 10 if(j != 0 ) { 11 System.out.println(j +" "+ KEYWORDS[i]); 12 } 13 14 }
源码分析
第五次题目集7-4源码复杂度分析如下图,复杂度较高,因为源码中循环语句多与if语句嵌套使用。

采坑心得
在第五次题目集7-4中出现如下问题
问题详情:pta测试点多个未过,在反反复复地,多次地测试下,发现代码的一个bug,在输入的文本中若存在print,则匹配int也可成功匹配,则会使int的出现次数多一,若存在int1,也会发现如上问题。
改进方案:在提取有效信息时在前后都添加一个空格,在匹配的正则表达式前后加上空格,这样能保证每一个被匹配成功的都是一个单独的关键字,防止出现单词中包含关键字的单词也被算为关键字。
心得:粗心,更为重要的是对正则表达式的理解不够透彻,日后要对所有所学的知识多多巩固,加强训练,深刻透彻的理解这些知识。
改进建议
在日后面对对象编程时要多多注重面对对象编程的三大特性,封装,继承,多态,并且加强对聚合,组合,关联,依赖等类之间关系的学习和理解,降低代码的耦合性,提高代码的质量,实现代码的可复用性。
总结
本月三次习题集难度较易,注重基础知识巩固。
正则表达式还没有透彻掌握如何灵活地使用。
对三大特性进一步理解。
对组合,聚合的区别和合理使用有更多认知。



浙公网安备 33010602011771号