PTA题目集4-6的总结与归纳
PTA题目集4-6的总结与归纳
前言:
4-6的题目知识点涵盖广泛,灵活性很高,大部分题目综合性较强,难度也相对较大。
这里做点简单的归纳整理,同各位一起学习进步。
目录:
①题目集4(7-2)、题目集5(7-4)两种日期类聚合设计的优劣比较
②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
③对三次题目集中用到的正则表达式技术的分析总结
④题目集5(7-4)中Java集合框架应用的分析总结
一:两种日期类聚合设计的优劣比较
7-2 日期问题面向对象设计(聚合一)
设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

设计如下几个类: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 //测试两个日期之间相差的天数
可以看出这两个题相似度极其的高,UML类图只是有了些许的差异,功能和输入上没有做变化。
先就我的一些看法分享如下:
1.聚合二就聚合一上将求下一年/月/日及上一年/月/日的功能封装在了每个各自的类里,结构上做的更加的清晰
2.聚合一的聚合连接是链式连接,一环扣一环,不能跨越调用,聚合二以dataUtil工具类作为连接体,以自身为中心,创建Year,Month,Day三个对象,便于理解也更加方便调用,更能体现高聚合,低耦合的性质。
聚合一Main类:
1 public class Main{ 2 public static void main(String[] args){ 3 Scanner input=new Scanner(System.in); 4 int c=input.nextInt(); 5 6 DateUtil dateUtil=new DateUtil(); 7 8 switch (c){ 9 case 1:{ 10 dateUtil.year= input.nextInt(); 11 dateUtil.month= input.nextInt(); 12 dateUtil.day= input.nextInt(); 13 dateUtil.setter(dateUtil.year, dateUtil.month, dateUtil.day); 14 int n= input.nextInt(); 15 16 if(dateUtil.checkInputValidity(dateUtil.year, dateUtil.month, dateUtil.day)){ 17 dateUtil.getNextNDays(n); 18 System.out.println(dateUtil.year+"-"+ dateUtil.month+"-"+ dateUtil.day); 19 } 20 21 22 23 break; 24 } 25 case 2: 26 case 3: 27 default: 28 System.out.println("Wrong Format"); 29 30 } 31 } 32 }
聚合二Main类:
1 public class Main { 2 public static void main(String[] args){ 3 Scanner input=new Scanner(System.in); 4 DateUtil dateUtil=new DateUtil(); 5 int choose= input.nextInt(); 6 int year=input.nextInt(); 7 int month=input.nextInt(); 8 int day= input.nextInt(); 9 dateUtil.setAll(year,month,day); 10 if(dateUtil.checkInputValidity(year,month,day)) { 11 switch (choose){ 12 case 1:{ 13 int n= input.nextInt(); 14 dateUtil.getNextNDay(n); 15 System.out.println(year+"-"+month+"-"+day+" next " +n+" days is:"+dateUtil.getYear()+"-"+ dateUtil.getMonth()+"-"+dateUtil.getDay()); 16 break; 17 18 } 19 case 2:{ 20 int n= input.nextInt(); 21 dateUtil.getBeforeNDay(n); 22 System.out.println(year+"-"+month+"-"+day+" previous " +n+" days is:"+dateUtil.getYear()+"-"+ dateUtil.getMonth()+"-"+dateUtil.getDay()); 23 }break; 24 case 3:{ 25 int toYear= input.nextInt(); 26 int toMonth= input.nextInt(); 27 int toDay= input.nextInt(); 28 if (dateUtil.checkInputValidity(toYear,toMonth,toDay)){ 29 if(year>toYear||(year==toYear&&month>toMonth)||(year==toYear&&month==toMonth&&day>toDay)) 30 { 31 dateUtil.getGapDays(toYear,toMonth,toDay,year,month,day); 32 System.out.println("The days between "+year+"-"+ month+"-"+ day+" and "+toYear+"-"+toMonth+"-"+toDay+" are:"+dateUtil.getGapDays(toYear,toMonth,toDay,year,month,day)); 33 } 34 else{ 35 dateUtil.getGapDays(year,month,day,toYear,toMonth,toDay); 36 System.out.println("The days between "+year+"-"+month+"-"+day+" and "+toYear+"-"+toMonth+"-"+toDay+" are:"+dateUtil.getGapDays(year,month,day,toYear,toMonth,toDay)); 37 38 } 39 //System.out.println("The days between "+year+"-"+month+"-"+day+" and "+toYear+"-"+toMonth+"-"+toDay+" are:"+dateUtil.getGapDays(year,month,day,toYear,toMonth,toDay)); 40 //} 41 } 42 43 }break; 44 default: 45 System.out.println("Wrong Format"); 46 } 47 48 }else 49 System.out.println("Wrong Format"); 50 } 51 }
可以看出,在Main类里两个结构也是大致差不多的,对象的调用,判断条件,输出格式,看起来较为冗杂,可以将输出封装在dataUtil里,进行调用就不会使主类显得复杂难看了。
这里我把当时我的难点分享在此:也就是计算两个日期的相差时间。
其实想想它并不难,可以理解为从一个日期小的时间开始一直往后加一天,用一个变量记录循环的次数,循环到日起大的日期就停下来,这样也就得到了循环的次数也就是相差的天数了。不过这样的一次一次的循环,执行效率可能并没有多好,但是老方法往往也是浅显易懂的,也正适合我这种初学的小白,理解起来就很轻松。往后学到了更多的内容后可以根据自身的情况来更改优化之前写过的代码,条条大路通罗马,方法多种多样总有弯路和捷径,我们也是在路上不断的探索和进步。
相差天数方法如下:
/**俩日期相差天数*/
int getGapDays(int year,int month,int day,int toYear,int toMonth,int toDay){
int flag=0;
while(true){
switch (month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:{
if (day+1<=31){
day=day+1;
}
else{
month+=1;
day=1;
}
break;
}
case 12:{
if (day+1<=31){
day=day+1;
}
else{
year+=1;
month=1;
day=1;
}
break;
}
case 4:
case 6:
case 9:
case 11:{
if (day+1<=30){
day=day+1;
}
else{
month+=1;
day=1;
}
break;
}
case 2:{
if(isLeapYear(year)){
if(day+1<=29){
day+=1;
}
else{
day=1;
month+=1;
}
}
else{
if(day+1<=28){
day+=1;
}
else{
day=1;
month+=1;
}
}
break;
}
}
flag++;
if(year==toYear&&month==toMonth&&day==toDay){
break;
}
}
return flag;
}
}
二:三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
编写程序,实现图形类的继承,并定义相应类对象并进行测试。
- 类Shape,无属性,有一个返回0.0的求图形面积的公有方法
public double getArea();//求图形面积 - 类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继承来的求面积方法,求圆的面积
- 类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继承来的求面积方法,求矩形的面积
- 类Ball,继承自Circle,其属性从父类继承,重写父类求面积方法,求球表面积,此外,定义一求球体积的方法
public double getVolume();//求球体积 - 类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,重写父类继承来的求面积方法,求立方体表面积,此外,定义一求立方体体积的方法
public double getVolume();//求立方体体积 - 注意:
- 每个类均有构造方法,且构造方法内必须输出如下内容:
Constructing 类名 - 每个类属性均为私有,且必须有getter和setter方法(可用Eclipse自动生成)
- 输出的数值均保留两位小数
主方法内,主要实现四个功能(1-4): 从键盘输入1,则定义圆类,从键盘输入圆的半径后,主要输出圆的面积; 从键盘输入2,则定义矩形类,从键盘输入矩形的宽和长后,主要输出矩形的面积; 从键盘输入3,则定义球类,从键盘输入球的半径后,主要输出球的表面积和体积; 从键盘输入4,则定义立方体类,从键盘输入立方体的宽、长和高度后,主要输出立方体的表面积和体积;
假如数据输入非法(包括圆、矩形、球及立方体对象的属性不大于0和输入选择值非1-4),系统输出Wrong Format
输入格式:
共四种合法输入
- 1 圆半径
- 2 矩形宽、长
- 3 球半径
- 4 立方体宽、长、高
输出格式:
按照以上需求提示依次输出
输入样例1:
在这里给出一组输入。例如:
1 1.0
输出样例1:
在这里给出相应的输出。例如:
Constructing Shape
Constructing Circle
Circle's area:3.14
输入样例2:
在这里给出一组输入。例如:
4 3.6 2.1 0.01211
输出样例2:
在这里给出相应的输出。例如:
Constructing Shape
Constructing Rectangle
Constructing Box
Box's surface area:15.26
Box's volume:0.09
输入样例3:
在这里给出一组输入。例如:
2 -2.3 5.110
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
UML类图:
![]()
这是一个简单的继承题目,Main作为主类,创建图形Shape对象,Shape有两个子类分别为Circle和Rectangle类,各自分别有个具体的对象子类Ball和Box类,且要求
构造一个对象就要输出构造的类型,这就需要在每一个构造方法里添加一个输出自己类名的方法。
在Circle和Rectangle类里需要有求面积的方法,Box和Ball除了求表面积外还需要添加求体积的方法。
以下为代码:
//import com.sun.scenario.effect.impl.sw.java.JSWBlend_HARD_LIGHTPeer;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int n= input.nextInt();
double radius=0;
double width=0,length=0,height=0;
switch (n){
case 1:{
radius=input.nextDouble();
if (radius<0)
{
System.out.println("Wrong Format");
break;
}
Circle a=new Circle();
a.setter(radius);
System.out.print("Circle's area:");
System.out.printf("%.2f",a.getArea());
break;
}
case 2:{
width=input.nextDouble();
length=input.nextDouble();
if (width<0||length<0)
{
System.out.println("Wrong Format");
break;
}
Rectangle b=new Rectangle();
b.setter(width,length);
System.out.print("Rectangle's area:");
System.out.printf("%.2f",b.getArea());
break;
}
case 3:{
radius=input.nextDouble();
if (radius<0)
{
System.out.println("Wrong Format");
break;
}
Ball c=new Ball();
c.setter(radius);
System.out.print("Ball's surface area:");
System.out.printf("%.2f\n",c.getArea());
System.out.print("Ball's volume:");
System.out.printf("%.2f\n",c.getVolume());
break;
}
case 4:{
width=input.nextDouble();
length= input.nextDouble();
height=input.nextDouble();
if (width<0||length<0||height<0)
{
System.out.println("Wrong Format");
break;
}
Box d=new Box();
d.setter(width,length,height);
System.out.print("Box's surface area:");
System.out.printf("%.2f\n",d.getArea());
System.out.print("Box's volume:");
System.out.printf("%.2f\n",d.getVolume());
break;
}
default:
System.out.println("Wrong Format");
}
}
}
class Shape{
double area=0.0;
Shape(){
System.out.println("Constructing Shape");
}
public double getArea(){
return area;
}
}
class Circle extends Shape{
private double radius;
void setter(double radius){
this.radius=radius;
}
Circle(){
System.out.println("Constructing Circle");
}
// @Override
public double getArea() {
return Math.PI*radius*radius;
}
}
class Rectangle extends Shape{
private double width,length;
Rectangle(){
System.out.println("Constructing Rectangle");
}
void setter(double width,double length){
this.width=width;
this.length=length;
}
// @Override
public double getArea() {
return width*length;
}
}
class Ball extends Circle{
private double radius;
Ball(){
System.out.println("Constructing Ball");
}
// @Override
void setter(double radius){
this.radius=radius;
}
public double getArea() {
return 4*Math.PI*radius*radius;
}
public double getVolume(){
return 4/3.0*Math.PI*radius*radius*radius;
}
}
class Box extends Rectangle{
private double width,length;
private double height;
Box(){
System.out.println("Constructing Box");
}
void setter(double width,double length,double height){
this.width=width;
this.length=length;
this.height=height;
}
// @Override
public double getArea() {
return 2*(width*length+width*height+length*height);
}
public double getVolume(){
return width*length*height;
}
}


浙公网安备 33010602011771号