第二次博客作业

1.前言

习题集总结

本月习题集知识点包括正则表达式的使用,聚合,继承,多态,接口。涵盖的内容很全面,说明老师出题认真,由简变难,

逐层增加难度。题集题量适中,有大题有小题,难度有难有易,适合巩固基础知识,拓展编程思维。

2.设计与分析

第四次题目集7-2与第五次题目集7-5两种聚合优劣比较

第四次题目集7-2题目情况

日期问题面向对象设计,应用程序共有三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

如下为题目要求的类图

 

 

第四次题目集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,也会发现如上问题。

改进方案:在提取有效信息时在前后都添加一个空格,在匹配的正则表达式前后加上空格,这样能保证每一个被匹配成功的都是一个单独的关键字,防止出现单词中包含关键字的单词也被算为关键字。

心得:粗心,更为重要的是对正则表达式的理解不够透彻,日后要对所有所学的知识多多巩固,加强训练,深刻透彻的理解这些知识。

 

改进建议

在日后面对对象编程时要多多注重面对对象编程的三大特性,封装,继承,多态,并且加强对聚合,组合,关联,依赖等类之间关系的学习和理解,降低代码的耦合性,提高代码的质量,实现代码的可复用性。

 

总结

本月三次习题集难度较易,注重基础知识巩固。

正则表达式还没有透彻掌握如何灵活地使用。

对三大特性进一步理解。

对组合,聚合的区别和合理使用有更多认知。

 

posted @ 2021-05-02 21:23  wendying  阅读(81)  评论(0)    收藏  举报