一、前言
二、所学内容
三、pta1-3题目集的分析
四、心得
--------------------------------------------------------------------------------------------------------------------
关于这个学期的Java,我认识到这门语言与上学期的c语言区别很大。在老师的引导下了
解关于面向对象程序设计的精髓所在。由于这门课前八章的关于语法的内容自己学习,在默
认了解Java程序设计基础的前提下,老师发布了pta题目集1以及2。随后在初步学习了类间
关系之后,老师发布了与之前题目有关联的迭代题目,要求我们能够设计类来解决问题。
----------------------------------------------------------------------------------------------------------------------
(1)Java相比于C语言的区别:
C:数据结构 + 算法。
Java:对象 + 消息。(两对象之间的交互手段)
(2)耦合与内聚:
耦合: 类与类之间的紧密性。
内聚: 类间的紧密性。
(Java类的设计要尽量服从弱耦合性与强内聚性)
(3)类间关系:
①关联 ②依赖 ③聚集(聚合、组合) ④泛化 ⑤实现
Ⅰ:关联耦合性比依赖强
Ⅱ:聚合与组合:
聚合:整体与部分生存期不一致。
组合:整体与部分生存期一致。
Ⅲ:耦合性:组合>聚合>关联>依赖
(4)类设计的七大原则中的1与7
1:单一职责原则
属性、类、方法 职责单一。
类中的属性一定要用得上。
计算出的不得算属性。
7:迪米特法则
①:不要和陌生人说话。
②:只和你的直接朋友通信。
(5)课堂实例:
老师在课堂上布置过一个关于雨刷控制器的作业
要求如下:
①:雨刷控制器包含(雨刷、控制器、刻度盘)
②:雨刷属性为雨刷的速度(0、6、12、18、30、60)r/min
控制器属性为雨刷的挡位(停止、间歇、低速、高速)
刻度盘属性为雨刷处于间歇挡位时的刻度(0、1、2、3)
③:使用MVC结构(Model、View、Controller)
④:尽可能的实现弱耦合性
经过老师的多次迭代实现了以上要求。
View
1 import java.util.Scanner; 2 3 public class Test { 4 5 public Test(){ 6 7 } 8 9 public static void main(String[] args) { 10 // TODO Auto-generated method stub 11 Scanner input = new Scanner(System.in); 12 13 Driver driver = new Driver(); 14 // Lever lever = new Lever(); 15 // Dial dial = new Dial(); 16 // Brush brush = new Brush(); 17 // Agent agent = new Agent(lever,dial,brush); 18 19 driver.work(); 20 21 } 22 23 public void view(int a,int b,int c){ 24 System.out.println("Lever's pos is:" + a); 25 System.out.println("Dial's pos is:" + b); 26 System.out.println("Brush's speed is:" + c); 27 } 28 }
Controller
1 import java.util.Scanner; 2 3 public class Driver { 4 5 public Driver(){ 6 7 } 8 9 public static void work(){ 10 Scanner input = new Scanner(System.in); 11 Lever lever = new Lever(); 12 Dial dial = new Dial(); 13 Brush brush = new Brush(); 14 Agent agent = new Agent(lever,dial,brush); 15 System.out.println("1为升档,2为降档,3为升刻度,4为降刻度"); 16 int choice=input.nextInt(); 17 Test test = new Test(); 18 while(true) { 19 switch(choice) { 20 case 1:lever.upPos();break; 21 case 2:lever.downPos();break; 22 case 3:dial.upPos();break; 23 case 4:dial.downPos();break; 24 } 25 26 agent.processSpeed(); 27 test.view(lever.getPos(),dial.getPos(),brush.getSpeed()); 28 System.out.println("1为升档,2为降档,3为升刻度,4为降刻度"); 29 choice = input.nextInt(); 30 } 31 } 32 }
中介类
public class Agent { private Lever lever; private Dial dial; private Brush brush; public Agent() { super(); // TODO Auto-generated constructor stub } public Agent(Lever lever, Dial dial, Brush brush) { super(); this.lever = lever; this.dial = dial; this.brush = brush; } public Lever getLever() { return lever; } public void setLever(Lever lever) { this.lever = lever; } public Dial getDial() { return dial; } public void setDial(Dial dial) { this.dial = dial; } public Brush getBrush() { return brush; } public void setBrush(Brush brush) { this.brush = brush; } public void processSpeed() { int speed = 0; switch(this.lever.getPos()) { case 1:speed = 0;break; case 2: switch(this.dial.getPos()) { case 1:speed = 4;break; case 2:speed = 6;break; case 3:speed = 12;break; }break; case 3:speed = 30;break; case 4:speed = 60;break; } this.brush.setSpeed(speed); } }
Model
1 public class Brush { 2 private int speed = 0; 3 4 public Brush() { 5 super(); 6 // TODO Auto-generated constructor stub 7 } 8 9 public Brush(int speed) { 10 super(); 11 this.speed = speed; 12 } 13 14 public int getSpeed() { 15 return speed; 16 } 17 18 public void setSpeed(int speed) { 19 this.speed = speed; 20 } 21 22 } 23 public class Dial { 24 private int pos = 1;//�̶�1,2,3 25 26 public Dial() { 27 super(); 28 // TODO Auto-generated constructor stub 29 } 30 31 public Dial(int pos) { 32 super(); 33 this.pos = pos; 34 } 35 36 public int getPos() { 37 return pos; 38 } 39 40 public void upPos() { 41 if(this.pos < 3) { 42 this.pos ++; 43 } 44 } 45 46 public void downPos() { 47 if(this.pos > 1) { 48 this.pos --; 49 } 50 } 51 52 53 } 54 public class Lever { 55 private int pos = 1;//��λ1,2,3,4 56 57 public Lever() { 58 super(); 59 // TODO Auto-generated constructor stub 60 } 61 62 public Lever(int pos) { 63 super(); 64 this.pos = pos; 65 } 66 67 public int getPos() { 68 return pos; 69 } 70 71 public void upPos() { 72 if(this.pos < 4) { 73 this.pos ++; 74 } 75 } 76 77 public void downPos() { 78 if(this.pos > 1) { 79 this.pos --; 80 } 81 }
----------------------------------------------------------------------------------------------------------------------
pta2-7-2
RS232是串口常用的通信协议,在异步通信模式下,串口可以一次发送5~8位数据,收发双方之间没有数据发送时线路维持高电平,相当于接收方持续收到数据“1”(称为空闲位),发送方有数据发送时,会在有效数据(5~8位,具体位数由通信双方提前设置)前加上1位起始位“0”,在有效数据之后加上1位可选的奇偶校验位和1位结束位“1”。请编写程序,模拟串口接收处理程序,注:假定有效数据是8位,奇偶校验位采用奇校验。
由0、1组成的二进制数据流。例如:11110111010111111001001101111111011111111101111
过滤掉空闲、起始、结束以及奇偶校验位之后的数据,数据之前加上序号和英文冒号。
如有多个数据,每个数据单独一行显示。
若数据不足11位或者输入数据全1没有起始位,则输出"null data",
若某个数据的结束符不为1,则输出“validate error”。
若某个数据奇偶校验错误,则输出“parity check error”。
若数据结束符和奇偶校验均不合格,输出“validate error”。
如:11011或11111111111111111。
例如:
1:11101011
2:01001101
3:validate error
源码如下
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 String s,ss,sss; 7 boolean flag=true; 8 s= input.nextLine(); 9 int lenth=s.length(); 10 if(!judge1(s)){ 11 System.out.print("null data"); 12 flag=false; 13 } 14 if(flag) { 15 int sum=0; 16 ss = getString(s); 17 int length1 = ss.length(); 18 for (int i = 0, j = 1; i <= length1 - 10; i += 10, j++) { 19 sss = ss.substring(i, i + 10); 20 int l2 = sss.length(); 21 sum=0; 22 for(int k=0;k<l2-1;k++){ 23 if(sss.charAt(k)=='1'){ 24 sum++; 25 } 26 } 27 if (sss.charAt(l2-1) != '1') { 28 System.out.println(j + ":validate error"); 29 } else if (sum%2==0) { 30 System.out.println(j + ":parity check error"); 31 } else { 32 System.out.println(j + ":" + sss.substring(0, l2 - 2)); 33 } 34 } 35 } 36 } 37 public static boolean judge1(String s){ 38 int lenth=s.length(); 39 if(lenth<11){ 40 return false; 41 } 42 else if(s.indexOf('0')==-1){ 43 return false; 44 } 45 return true; 46 } 47 public static String getString(String s){ 48 int i=s.indexOf('0'); 49 int length=s.length(); 50 String ss; 51 ss=s.substring(i+1,i+11); 52 for(;;){ 53 if(s.indexOf('0',i+10)==-1) 54 break; 55 i=s.indexOf('0',i+11); 56 if(i==-1) 57 break; 58 if(i+11>length) 59 break; 60 ss=ss+s.substring(i+1,i+11); 61 } 62 return ss; 63 } 64 }
踩坑心得
①:对于题目理解不充分,后在网上查阅相关资料解决该问题。
②:对于输入字符串的分割标识符不够清楚,后改进。
pta3-7-1
7-1 用类解一元二次方程式 (10 分)定义一个代表一元二次方程ax2+bx+c=0的类QuadraticEquation,其属性为三个系数a、b、c(均为私有属性),类中定义的方法参考main方法中的代码。main方法源码:
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 7 double a = Double.parseDouble(input.next()); 8 double b = Double.parseDouble(input.next()); 9 double c = Double.parseDouble(input.next()); 10 11 if(a == 0){ 12 System.out.println("Wrong Format"); 13 System.exit(0); 14 } 15 16 //create a QuadraticEquation object 17 QuadraticEquation equation = new QuadraticEquation(a, b, c); 18 //get value of b * b - 4 * a * c 19 double discriminant = equation.getDiscriminant(); 20 21 System.out.println("a=" + equation.getA() + 22 ",b=" + equation.getB() + 23 ",c=" + equation.getC()+":"); 24 25 if (discriminant < 0) { 26 System.out.println("The equation has no roots."); 27 } 28 else if (discriminant == 0) 29 { 30 System.out.println("The root is " + 31 String.format("%.2f", equation.getRoot1())); 32 } 33 else // (discriminant >= 0) 34 { 35 System.out.println("The roots are " + 36 String.format("%.2f", equation.getRoot1()) 37 + " and " + String.format("%.2f", equation.getRoot2())); 38 } 39 } 40 } 41 42 class QuadraticEquation{ 43 //your code 44 }
注意:须提交完整源码,包括Main类。
在一行中输入a、b、c的值,可以用一个或多个空格或回车符分开。
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input = new Scanner(System.in); 6 7 double a = Double.parseDouble(input.next()); 8 double b = Double.parseDouble(input.next()); 9 double c = Double.parseDouble(input.next()); 10 11 if(a == 0){ 12 System.out.println("Wrong Format"); 13 System.exit(0); 14 } 15 16 //create a QuadraticEquation object 17 QuadraticEquation equation = new QuadraticEquation(a,b,c); 18 //get value of b * b - 4 * a * c 19 double discriminant = equation.getDiscriminant(); 20 21 System.out.println("a=" + equation.getA() + 22 ",b=" + equation.getB() + 23 ",c=" + equation.getC()+":"); 24 25 if (discriminant < 0) { 26 System.out.println("The equation has no roots."); 27 } 28 else if (discriminant == 0) 29 { 30 System.out.println("The root is " + 31 String.format("%.2f", equation.getRoot1())); 32 } 33 else // (discriminant >= 0) 34 { 35 System.out.println("The roots are " + 36 String.format("%.2f", equation.getRoot1()) 37 + " and " + String.format("%.2f", equation.getRoot2())); 38 } 39 } 40 } 41 42 43 44 class QuadraticEquation{ 45 46 private double a; 47 private double b; 48 private double c; 49 private double discriminant; 50 private double root1; 51 private double root2; 52 53 public QuadraticEquation(){ 54 55 } 56 57 public QuadraticEquation(double a,double b,double c){ 58 this.a=a; 59 this.b=b; 60 this.c=c; 61 } 62 63 public double getA() { 64 return a; 65 } 66 67 public void setA(double a) { 68 this.a = a; 69 } 70 71 public double getB() { 72 return b; 73 } 74 75 public void setB(double b) { 76 this.b = b; 77 } 78 79 public double getC() { 80 return c; 81 } 82 83 public void setC(double c) { 84 this.c = c; 85 } 86 87 public double getDiscriminant() { 88 discriminant = b * b - 4 * a * c; 89 return discriminant; 90 } 91 92 public void setDiscriminant(double discriminant) { 93 this.discriminant = discriminant; 94 } 95 96 public double getRoot1() { 97 root1 = ((-b + Math.sqrt(discriminant))/ (2 * a)); 98 return root1; 99 } 100 101 public void setRoot1(double root1) { 102 this.root1 = root1; 103 } 104 105 public double getRoot2() { 106 root2 = ((-b - Math.sqrt(discriminant))/ (2 * a)); 107 return root2; 108 } 109 110 public void setRoot2(double root2) { 111 this.root2 = root2; 112 } 113 114 }
心得:
1、用类来解决这道题明显的降低了耦合性,并且实现了单一职责原则
不用类的方法如下:
1 import java.lang.Math; 2 import java.util.Scanner; 3 public class Main { 4 public static void main(String[] args){ 5 Scanner input=new Scanner(System.in); 6 int flag=0; 7 double[] eqn=new double[3]; 8 double[] roots=new double[2]; 9 int i=0,j=0; 10 for(;i<3;i++){ 11 eqn[i]=input.nextDouble(); 12 } 13 flag=solveQuadratic(eqn,roots); 14 if(flag==0){ 15 if(eqn[0]==0){ 16 System.out.println("Wrong Format"); 17 } 18 else 19 System.out.println("The equation has no roots"); 20 } 21 else if(flag==1){ 22 System.out.println("The equation has one root: "+String.format("%.4f",roots[0])); 23 } 24 else if(flag==2){ 25 System.out.println("The equation has two roots: "+String.format("%.4f",roots[0])+" and "+String.format("%.4f",roots[1])); 26 } 27 } 28 public static int solveQuadratic(double[] eqn, double[] roots){ 29 double a=eqn[0]; 30 double b=eqn[1]; 31 double c=eqn[2]; 32 double d=b*b; 33 double e=4*a*c; 34 if(a==0){ 35 return 0; 36 } 37 else { 38 if(d-e<0){ 39 return 0; 40 } 41 else if(d-e==0){ 42 if(b!=0||c!=0) { 43 roots[0] = (-b) / (2 * a); 44 return 1; 45 } 46 else if(b==0&&c==0){ 47 roots[0]= 0.0; 48 return 1; 49 } 50 } 51 else{ 52 roots[0]=(-b+Math.sqrt(d-e))/(2*a); 53 roots[1]=(-b-Math.sqrt(d-e))/(2*a); 54 return 2; 55 } 56 } 57 return 0; 58 } 59 }
pta-3-7-2
7-2 日期类设计 (30 分)参考题目集二中和日期相关的程序,设计一个类DateUtil,该类有三个私有属性year、month、day(均为整型数),其中,year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 除了创建该类的构造方法、属性的getter及setter方法外,需要编写如下方法:
public boolean checkInputValidity();//检测输入的年、月、日是否合法 public boolean isLeapYear(int year);//判断year是否为闰年 public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期 public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期 public boolean compareDates(DateUtil date);//比较当前日期与date的大小(先后) public boolean equalTwoDates(DateUtil date);//判断两个日期是否相等 public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数 public String showDate();//以“year-month-day”格式返回日期值
应用程序共测试三个功能:
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
程序主方法如下:
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner input = new Scanner(System.in); 6 int year = 0; 7 int month = 0; 8 int day = 0; 9 10 int choice = input.nextInt(); 11 12 if (choice == 1) { // test getNextNDays method 13 int m = 0; 14 year = Integer.parseInt(input.next()); 15 month = Integer.parseInt(input.next()); 16 day = Integer.parseInt(input.next()); 17 18 DateUtil date = new DateUtil(year, month, day); 19 20 if (!date.checkInputValidity()) { 21 System.out.println("Wrong Format"); 22 System.exit(0); 23 } 24 25 m = input.nextInt(); 26 27 if (m < 0) { 28 System.out.println("Wrong Format"); 29 System.exit(0); 30 } 31 32 System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:"); 33 System.out.println(date.getNextNDays(m).showDate()); 34 } else if (choice == 2) { // test getPreviousNDays method 35 int n = 0; 36 year = Integer.parseInt(input.next()); 37 month = Integer.parseInt(input.next()); 38 day = Integer.parseInt(input.next()); 39 40 DateUtil date = new DateUtil(year, month, day); 41 42 if (!date.checkInputValidity()) { 43 System.out.println("Wrong Format"); 44 System.exit(0); 45 } 46 47 n = input.nextInt(); 48 49 if (n < 0) { 50 System.out.println("Wrong Format"); 51 System.exit(0); 52 } 53 54 System.out.print( 55 date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:"); 56 System.out.println(date.getPreviousNDays(n).showDate()); 57 } else if (choice == 3) { //test getDaysofDates method 58 year = Integer.parseInt(input.next()); 59 month = Integer.parseInt(input.next()); 60 day = Integer.parseInt(input.next()); 61 62 int anotherYear = Integer.parseInt(input.next()); 63 int anotherMonth = Integer.parseInt(input.next()); 64 int anotherDay = Integer.parseInt(input.next()); 65 66 DateUtil fromDate = new DateUtil(year, month, day); 67 DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay); 68 69 if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { 70 System.out.println("The days between " + fromDate.showDate() + 71 " and " + toDate.showDate() + " are:" 72 + fromDate.getDaysofDates(toDate)); 73 } else { 74 System.out.println("Wrong Format"); 75 System.exit(0); 76 } 77 } 78 else{ 79 System.out.println("Wrong Format"); 80 System.exit(0); 81 } 82 } 83 }
有三种输入方式(以输入的第一个数字划分[1,3]):
Wrong Format
year1-month1-day1 next n days is:year2-month2-day2
year1-month1-day1 previous n days is:year2-month2-day2
The days between year1-month1-day1 and year2-month2-day2 are:值
源码如下:
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner input = new Scanner(System.in); 6 int year = 0; 7 int month = 0; 8 int day = 0; 9 10 int choice = input.nextInt(); 11 12 if (choice == 1) { // test getNextNDays method 13 int m = 0; 14 year = Integer.parseInt(input.next()); 15 month = Integer.parseInt(input.next()); 16 day = Integer.parseInt(input.next()); 17 18 DateUtil date = new DateUtil(year, month, day); 19 20 if (!date.checkInputValidity()) { 21 System.out.println("Wrong Format"); 22 System.exit(0); 23 } 24 25 m = input.nextInt(); 26 27 if (m < 0) { 28 System.out.println("Wrong Format"); 29 System.exit(0); 30 } 31 32 System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:"); 33 System.out.println(date.getNextNDays(m).showDate()); 34 } else if (choice == 2) { // test getPreviousNDays method 35 int n = 0; 36 year = Integer.parseInt(input.next()); 37 month = Integer.parseInt(input.next()); 38 day = Integer.parseInt(input.next()); 39 40 DateUtil date = new DateUtil(year, month, day); 41 42 if (!date.checkInputValidity()) { 43 System.out.println("Wrong Format"); 44 System.exit(0); 45 } 46 47 n = input.nextInt(); 48 49 if (n < 0) { 50 System.out.println("Wrong Format"); 51 System.exit(0); 52 } 53 54 System.out.print( 55 date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:"); 56 System.out.println(date.getPreviousNDays(n).showDate()); 57 } else if (choice == 3) { //test getDaysofDates method 58 year = Integer.parseInt(input.next()); 59 month = Integer.parseInt(input.next()); 60 day = Integer.parseInt(input.next()); 61 62 int anotherYear = Integer.parseInt(input.next()); 63 int anotherMonth = Integer.parseInt(input.next()); 64 int anotherDay = Integer.parseInt(input.next()); 65 66 DateUtil fromDate = new DateUtil(year, month, day); 67 DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay); 68 69 if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { 70 System.out.println("The days between " + fromDate.showDate() + 71 " and " + toDate.showDate() + " are:" 72 + fromDate.getDaysofDates(toDate)); 73 } else { 74 System.out.println("Wrong Format"); 75 System.exit(0); 76 } 77 } 78 else{ 79 System.out.println("Wrong Format"); 80 System.exit(0); 81 } 82 } 83 } 84 class DateUtil { 85 86 private int year; 87 private int month; 88 private int day; 89 90 public DateUtil(){ 91 92 } 93 94 public int getYear() { 95 return year; 96 } 97 98 public void setYear(int year) { 99 this.year = year; 100 } 101 102 public int getMonth() { 103 return month; 104 } 105 106 public void setMonth(int month) { 107 this.month = month; 108 } 109 110 public int getDay() { 111 return day; 112 } 113 114 public void setDay(int day) { 115 this.day = day; 116 } 117 118 public DateUtil(int year, int month, int day){ 119 this.year = year; 120 this.month = month; 121 this.day = day; 122 } 123 124 public boolean checkInputValidity(){ 125 if (year < 2021 && year > 1819 && month > 0 && month < 13 && day > 0 && day < 32) { 126 if (isLeapYear(year)) { 127 if ((day>29&&month==2)||(day>30&&month==4)||(day>30&&month==6)||(day>30&&month==9)||(day>30&&month==11)){ 128 return false; 129 } else { 130 return true; 131 } 132 } 133 else { 134 if ((day>28&&month==2)||(day>30&&month==4)||(day>30&&month==6)||(day>30&&month==9)||(day>30&&month==11)) { 135 return false; 136 } else { 137 return true; 138 } 139 } 140 } 141 else { 142 return false; 143 } 144 }//检测输入的年、月、日是否合法 145 public boolean isLeapYear(int year){ 146 if(year%400==0){ 147 return true; 148 } 149 else if(year%4==0&&year%100!=0){ 150 return true; 151 } 152 else { 153 return false; 154 } 155 }//判断year是否为闰年 156 public DateUtil getNextNDays(int n) { 157 while(n>=366) { 158 if (isLeapYear(year+1)) { 159 if(month>2){ 160 n-=366; 161 year++; 162 } 163 else { 164 n-=365; 165 year++; 166 } 167 } 168 else if(isLeapYear(year)){ 169 if((month<2)||(month==2&&day<29)){ 170 n-=366; 171 year++; 172 } 173 else { 174 n-=365; 175 year++; 176 } 177 } 178 else{ 179 n-=365; 180 year++; 181 } 182 } 183 if(month == 2 && day + n > 29 && isLeapYear(year)){ 184 this.month++; 185 this.day = day + n - 29; 186 } 187 else if (month == 12 && day + n > 31) { 188 this.year++; 189 this.month = 1; 190 this.day = day + n - 31; 191 } 192 else if(month == 2 && day + n > 28 && !isLeapYear(year)){ 193 this.month++; 194 this.day = day + n - 28; 195 } 196 else if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) && day + n > 31) { 197 this.month++; 198 this.day = day + n - 31; 199 } else if ((month == 4 || month == 6 || month == 9 || month == 11) && day + n > 30) { 200 this.month++; 201 this.day = day + n - 30; 202 } else { 203 this.day = day + n; 204 } 205 while ((isLeapYear(year)&&(month==2&&(day>29||day<0)))||(!isLeapYear(year)&&(month==2&&(day>29||day<0)))||((month==4||month==6||month==9||month==11)&&(day>30||day<0))||(day<0||day>31)){ 206 if(month == 2 && day > 29 && isLeapYear(year)){ 207 this.month++; 208 this.day = day - 29; 209 } 210 else if (month == 12 && day > 31) { 211 this.year++; 212 this.month = 1; 213 this.day = day - 31; 214 } 215 else if(month == 2 && day > 28 && !isLeapYear(year)){ 216 this.month++; 217 this.day = day - 28; 218 } 219 else if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) && day > 31) { 220 this.month++; 221 this.day = day - 31; 222 } else if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) { 223 this.month++; 224 this.day = day - 30; 225 } 226 } 227 return this; 228 } 229 public DateUtil getPreviousNDays(int n){ 230 while(n>=366) { 231 if (isLeapYear(year-1)) { 232 if(month>2){ 233 n-=365; 234 year--; 235 } 236 else { 237 n-=366; 238 year--; 239 } 240 } 241 else if(isLeapYear(year)){ 242 if((month<2)||(month==2&&day<29)){ 243 n-=365; 244 year--; 245 } 246 else { 247 n-=366; 248 year--; 249 } 250 } 251 else{ 252 n-=365; 253 year--; 254 } 255 } 256 if(month == 3 && day - n <= 0 && isLeapYear(year)){ 257 this.month--; 258 this.day = 29 + (day - n); 259 } 260 else if(month == 3 && day - n <= 0 && !isLeapYear(year)){ 261 this.month--; 262 this.day = 28 + (day - n); 263 } 264 else if (month == 1 && day - n <= 0) { 265 this.year--; 266 this.month = 12; 267 this.day = 31 + (day - n); 268 } 269 else if ((month == 2 || month == 4 || month == 6 || month == 8 || month == 9 || month == 11) && day - n <= 0) { 270 this.month--; 271 this.day = 31 + (day - n); 272 } else if ((month == 5 || month == 7 || month == 10 || month == 12) && day - n <= 0) { 273 this.month--; 274 this.day = 30 + (day - n); 275 } else { 276 this.day = day - n; 277 } 278 while (day<1){ 279 if(month == 3 && day <= 0 && isLeapYear(year)){ 280 this.month--; 281 this.day = 29 + day; 282 } 283 else if(month == 3 && day <= 0 && !isLeapYear(year)){ 284 this.month--; 285 this.day = 28 + day; 286 } 287 else if (month == 1 && day <= 0) { 288 this.year--; 289 this.month = 12; 290 this.day = 31 + day; 291 } 292 else if ((month == 2 || month == 4 || month == 6 || month == 8 || month == 9 || month == 11) && day <= 0) { 293 this.month--; 294 this.day = 31 + day; 295 } else if ((month == 5 || month == 7 || month == 10 || month == 12) && day <= 0) { 296 this.month--; 297 this.day = 30 + day; 298 } 299 } 300 return this; 301 } 302 public boolean compareDates(DateUtil date){ 303 if(year > date.year){ 304 return true; 305 } 306 else if(year < date.year){ 307 return false; 308 } 309 else{ 310 if(month > date.month){ 311 return true; 312 } 313 else if(month < date.month){ 314 return false; 315 } 316 else { 317 if(day > date.day){ 318 return true; 319 } 320 else if(day < date.day){ 321 return false; 322 } 323 } 324 } 325 return true; 326 } 327 public boolean equalTwoDates(DateUtil date){ 328 if(date.year == year && date.month == month && date.day == day){ 329 return true; 330 } 331 return false; 332 } 333 public int getDaysofDates(DateUtil date){ 334 int aYear = 1820; 335 int aMonth = 1; 336 int sumDays = 0; 337 int sumDays1 = 0; 338 int i=0; 339 while (aYear<date.year){ 340 if(isLeapYear(aYear)){ 341 sumDays+=366; 342 } 343 else { 344 sumDays+=365; 345 } 346 aYear++; 347 } 348 int []a; 349 a=new int[]{31,28,31,30,31,30,31,31,30,31,30,31}; 350 int []b; 351 b=new int[]{31,29,31,30,31,30,31,31,30,31,30,31}; 352 while (aMonth<date.month){ 353 if(isLeapYear(aYear)){ 354 sumDays+=b[i]; 355 } 356 else { 357 sumDays+=a[i]; 358 } 359 aMonth++; 360 i++; 361 } 362 sumDays+=date.day; 363 aYear=1820; 364 aMonth=1; 365 i=0; 366 while (aYear<this.year){ 367 if(isLeapYear(aYear)){ 368 sumDays1+=366; 369 } 370 else { 371 sumDays1+=365; 372 } 373 aYear++; 374 } 375 while (aMonth<this.month){ 376 if(isLeapYear(aYear)){ 377 sumDays1+=b[i]; 378 } 379 else { 380 sumDays1+=a[i]; 381 } 382 aMonth++; 383 i++; 384 } 385 sumDays1+=this.day; 386 return Math.abs(sumDays1-sumDays); 387 } 388 public String showDate(){ 389 String s1 = Integer.toString(year); 390 String s2 = Integer.toString(month); 391 String s3 = Integer.toString(day); 392 return s1 + "-" + s2 + "-" + s3; 393 } 394 }
pta-3-7-3
7-3 日期问题面向对象设计(聚合一) (30 分)参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
有三种输入方式(以输入的第一个数字划分[1,3]):
Wrong Format
year-month-day
year-month-day
天数值
源码如下:
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner input = new Scanner(System.in); 6 int year = 0; 7 int month = 0; 8 int day = 0; 9 10 int choice = input.nextInt(); 11 12 if (choice == 1) { // test getNextNDays method 13 int m = 0; 14 year = Integer.parseInt(input.next()); 15 month = Integer.parseInt(input.next()); 16 day = Integer.parseInt(input.next()); 17 18 DateUtil date = new DateUtil(year, month, day); 19 20 if (!date.checkInputValidity()) { 21 System.out.println("Wrong Format"); 22 System.exit(0); 23 } 24 25 m = input.nextInt(); 26 27 if (m < 0) { 28 System.out.println("Wrong Format"); 29 System.exit(0); 30 } 31 32 33 System.out.println(date.getNextNDays(m).showDate()); 34 } else if (choice == 2) { // test getPreviousNDays method 35 int n = 0; 36 year = Integer.parseInt(input.next()); 37 month = Integer.parseInt(input.next()); 38 day = Integer.parseInt(input.next()); 39 40 DateUtil date = new DateUtil(year, month, day); 41 42 if (!date.checkInputValidity()) { 43 System.out.println("Wrong Format"); 44 System.exit(0); 45 } 46 47 n = input.nextInt(); 48 49 if (n < 0) { 50 System.out.println("Wrong Format"); 51 System.exit(0); 52 } 53 54 System.out.println(date.getPreviousNDays(n).showDate()); 55 } else if (choice == 3) { //test getDaysofDates method 56 year = Integer.parseInt(input.next()); 57 month = Integer.parseInt(input.next()); 58 day = Integer.parseInt(input.next()); 59 60 int anotherYear = Integer.parseInt(input.next()); 61 int anotherMonth = Integer.parseInt(input.next()); 62 int anotherDay = Integer.parseInt(input.next()); 63 64 DateUtil fromDate = new DateUtil(year, month, day); 65 DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay); 66 67 if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { 68 System.out.println(fromDate.getDaysofDates(toDate)); 69 } else { 70 System.out.println("Wrong Format"); 71 System.exit(0); 72 } 73 } 74 else{ 75 System.out.println("Wrong Format"); 76 System.exit(0); 77 } 78 } 79 } 80 class DateUtil { 81 82 public DateUtil(){ 83 84 } 85 86 public Day getD() { 87 return d; 88 } 89 90 public void setD(Day d) { 91 this.d = d; 92 } 93 94 Day d=new Day(); 95 96 public DateUtil(int year, int month, int day){ 97 d.setValue(day); 98 d.m.setValue(month); 99 d.m.y.setValue(year); 100 } 101 102 boolean checkInputValidity(){ 103 if(d.validate()&&d.m.validate()&&d.m.y.validate()){ 104 return true; 105 } 106 else return false; 107 }//检测输入的年、月、日是否合法 108 boolean equalTwodates(DateUtil date){ 109 if(this.d.getValue()==date.d.getValue()&& 110 this.d.m.getValue()==date.d.m.getValue()&& 111 this.d.m.y.getValue()==date.d.m.y.getValue()){ 112 return true; 113 } 114 else return false; 115 } 116 boolean compareTwoDates(DateUtil date){ 117 if(date.d.m.y.getValue()>this.d.m.y.getValue()){ 118 return true; 119 } 120 else if(date.d.m.y.getValue()==this.d.m.y.getValue()&& 121 date.d.m.getValue()>this.d.m.getValue()){ 122 return true; 123 } 124 else if(date.d.m.y.getValue()==this.d.m.y.getValue()&& 125 date.d.m.getValue()==this.d.m.getValue()&& 126 date.d.getValue()>this.d.getValue()){ 127 return true; 128 } 129 else if(equalTwodates(date)){ 130 return true; 131 } 132 else 133 return false; 134 } 135 public DateUtil getNextNDays(int n) { 136 while(n>=366) { 137 int flag=0; 138 d.m.y.yearIncrement(); 139 if (d.m.y.isLeapYear()) { 140 flag=1; 141 if(d.m.getValue()>2){ 142 n-=366; 143 d.m.y.yearIncrement(); 144 } 145 else { 146 n-=365; 147 d.m.y.yearIncrement(); 148 } 149 } 150 d.m.y.yearReduction(); 151 if(d.m.y.isLeapYear()){ 152 if((d.m.getValue()<2)||(d.m.getValue()==2&&d.getValue()<29)){ 153 n-=366; 154 d.m.y.yearIncrement(); 155 } 156 else { 157 n-=365; 158 d.m.y.yearIncrement(); 159 } 160 } 161 else if(flag==0){ 162 n-=365; 163 d.m.y.yearIncrement(); 164 } 165 } 166 if(n>0){ 167 while (n>0){ 168 d.dayIncrement(); 169 n--; 170 }} 171 else if(n<0) { 172 while (n <0) { 173 d.dayReduction(); 174 n++; 175 } 176 } 177 return this; 178 } 179 public DateUtil getPreviousNDays(int n){ 180 while(n>=366) { 181 int flag=0; 182 d.m.y.yearReduction(); 183 if(d.m.y.isLeapYear()){ 184 flag=1; 185 if(d.m.getValue()>2){ 186 n-=365; 187 d.m.y.yearReduction(); 188 } 189 else { 190 n-=366; 191 d.m.y.yearReduction(); 192 } 193 } 194 d.m.y.yearIncrement(); 195 if (d.m.y.isLeapYear()){ 196 if((d.m.getValue()<2)||(d.m.getValue()==2&&d.getValue()<29)){ 197 n-=365; 198 d.m.y.yearReduction(); 199 } 200 else { 201 n-=366; 202 d.m.y.yearReduction(); 203 } 204 } 205 else if(flag==0){ 206 n-=365; 207 d.m.y.yearReduction(); 208 } 209 } 210 if(n>0){ 211 while (n>0){ 212 d.dayReduction(); 213 n--; 214 }} 215 else if(n<0) { 216 while (n <0) { 217 d.dayIncrement(); 218 n++; 219 } 220 } 221 return this; 222 } 223 224 public int getDaysofDates(DateUtil date){ 225 int sum=0; 226 int sum1=0; 227 int sum2=0; 228 int year1=date.d.m.y.getValue(); 229 int year2=this.d.m.y.getValue(); 230 if(compareTwoDates(date)){ 231 if(equalTwodates(date)) 232 return 0; 233 else { 234 if(date.d.m.y.getValue()==this.d.m.y.getValue()|| 235 date.d.m.y.getValue()-this.d.m.y.getValue()==1){ 236 while (true){ 237 this.d.dayIncrement(); 238 sum++; 239 if(date.d.m.getValue()==this.d.m.getValue()&& 240 date.d.getValue()==this.d.getValue()){ 241 break; 242 } 243 } 244 return sum; 245 } 246 else { 247 while (true){ 248 date.d.dayReduction(); 249 sum2++; 250 if(date.d.getValue()==1&&date.d.m.getValue()==1) 251 break; 252 } 253 while (true){ 254 this.d.m.y.yearIncrement(); 255 if(this.d.m.y.isLeapYear()) 256 sum+=366; 257 else sum+=365; 258 if(this.d.m.y.getValue()==date.d.m.y.getValue()-1) 259 break; 260 } 261 while (true){ 262 this.d.dayIncrement(); 263 sum1++; 264 if(this.d.getValue()==1&&this.d.m.getValue()==1) 265 break; 266 } 267 sum=sum1+sum2+sum; 268 } 269 } 270 } 271 else { 272 if(date.d.m.y.getValue()==this.d.m.y.getValue()|| 273 this.d.m.y.getValue()-date.d.m.y.getValue()==1){ 274 while (true){ 275 date.d.dayIncrement(); 276 sum++; 277 if(this.d.m.getValue()==date.d.m.getValue()&& 278 this.d.getValue()==date.d.getValue()){ 279 break; 280 } 281 } 282 return sum; 283 } 284 else { 285 while (true){ 286 date.d.dayIncrement(); 287 sum1++; 288 if(date.d.getValue()==31&&date.d.m.getValue()==12) 289 break; 290 } 291 while (true){ 292 this.d.dayReduction(); 293 sum2++; 294 if(this.d.getValue()==1&&this.d.m.getValue()==1) 295 break; 296 } 297 while (true){ 298 date.d.m.y.yearIncrement(); 299 if(date.d.m.y.isLeapYear()) 300 sum+=366; 301 else sum+=365; 302 if(this.d.m.y.getValue()==date.d.m.y.getValue()+1) 303 break; 304 } 305 sum=sum1+sum2+sum; 306 } 307 } 308 return sum; 309 } 310 public String showDate(){ 311 String s1 = Integer.toString(d.m.y.getValue()); 312 String s2 = Integer.toString(d.m.getValue()); 313 String s3 = Integer.toString(d.getValue()); 314 return s1 + "-" + s2 + "-" + s3; 315 } 316 } 317 class Day { 318 319 Month m=new Month(); 320 private int value; 321 int []a=new int[]{31,28,31,30,31,30,31,31,30,31,30,31}; 322 323 public Day(){ 324 325 } 326 327 public Day(int yearvalue,int monthvalue,int dayvalue){ 328 this.value=dayvalue; 329 m.setValue(monthvalue); 330 m.y.setValue(yearvalue); 331 } 332 333 public Month getM() { 334 return m; 335 } 336 337 public void setM(Month m) { 338 this.m = m; 339 } 340 341 public int getValue() { 342 return value; 343 } 344 345 public void setValue(int value) { 346 this.value = value; 347 } 348 349 void resetMin(){ 350 value=1; 351 } 352 353 void resetMax(){ 354 if(m.y.isLeapYear()){ 355 if(m.getValue()==2) 356 value=29; 357 else { 358 value=a[m.getValue()-1]; 359 } 360 } 361 else { 362 value=a[m.getValue()-1]; 363 } 364 } 365 366 boolean validate(){ 367 if(value<0||value>31){ 368 return false; 369 } 370 else { 371 if (m.y.isLeapYear()) { 372 if ((value>29&&m.getValue()==2)||(value>30&&m.getValue()==4)||(value>30&&m.getValue()==6)||(value>30&&m.getValue()==9)|| 373 (value>30&&m.getValue()==11)){ 374 return false; 375 } else { 376 return true; 377 } 378 } 379 else { 380 if ((value>28&&m.getValue()==2)||(value>30&&m.getValue()==4)||(value>30&&m.getValue()==6)||(value>30&&m.getValue()==9)|| 381 (value>30&&m.getValue()==11)) { 382 return false; 383 } else { 384 return true; 385 } 386 } 387 } 388 } 389 390 void dayIncrement(){ 391 value++; 392 if(m.y.isLeapYear()){ 393 a[1]=29; 394 if(value>a[m.getValue()-1]){ 395 m.monthIncrement(); 396 resetMin(); 397 } 398 a[1]=28; 399 } 400 else { 401 if(value>a[m.getValue()-1]){ 402 m.monthIncrement(); 403 resetMin(); 404 } 405 } 406 } 407 408 void dayReduction(){ 409 value--; 410 if(value<1){ 411 m.monthReduction(); 412 resetMax(); 413 } 414 } 415 } 416 class Month { 417 418 private int value; 419 Year y=new Year(); 420 421 public Month(){ 422 423 } 424 425 public Month(int yearvalue,int monthvalue){ 426 y.setValue(yearvalue); 427 this.value=monthvalue; 428 } 429 430 public int getValue() { 431 return value; 432 } 433 434 public void setValue(int value) { 435 this.value = value; 436 } 437 438 public Year getY() { 439 return y; 440 } 441 442 public void setY(Year y) { 443 this.y = y; 444 } 445 446 void resetMin(){ 447 value=1; 448 } 449 450 void resetMax(){ 451 value=12; 452 } 453 454 boolean validate(){ 455 if(value<1||value>12){ 456 return false; 457 } 458 else 459 return true; 460 } 461 462 void monthIncrement(){ 463 value++; 464 if(value==13){ 465 resetMin(); 466 y.yearIncrement(); 467 } 468 } 469 470 void monthReduction(){ 471 value--; 472 if(value==0){ 473 resetMax(); 474 y.yearReduction(); 475 } 476 } 477 478 } 479 class Year { 480 481 public Year(){ 482 483 } 484 485 public Year(int value){ 486 this.value=value; 487 } 488 489 public int getValue() { 490 return value; 491 } 492 493 public void setValue(int value) { 494 this.value = value; 495 } 496 497 private int value; 498 499 boolean isLeapYear(){ 500 if(value%400==0){ 501 return true; 502 } 503 else if(value%4==0&&value%100!=0){ 504 return true; 505 } 506 else { 507 return false; 508 } 509 } 510 511 boolean validate(){ 512 if(value<1900||value>2050){ 513 return false; 514 } 515 else 516 return true; 517 } 518 519 void yearIncrement(){ 520 value++; 521 } 522 523 void yearReduction(){ 524 value--; 525 } 526 527 }
以上两题,后一题是前一题的迭代代码
第二题中有着第一题没有的需求,即类与类的聚合关系
踩坑心得:
1、在判断年月日输入数据是否合法时,由于每月最大天数是由一个数组决定,而
这个数组的长度是已定的,当输入不属于1-12月时会出现数组越界错误。
解决方法:在此前可以先判断月的输入是否规范,再来判断天数输入的合法性。
2、在输出后n天和前n天时,之前的算法是球n次后一天(前)。结果在n比较大
的时候会发生超时错误。
解决方法:先将n进行处理,即将n处理在一年之类的天数,再求n次后一天。
3、出现代码长度超过限制的问题
解决方法:将代码里的无用代码和重复代码进行省略处理。
4、采用后面的方法明显降低了耦合性。
-----------------------------------------------------------------------------------------------------------------------------
改进建议:
在pta-3-7-4中
需要在DateUtil类中加入两个方法来判断后(前)一天的情况
这样在运用后(前)一天的方法之后就可以直接使用那个方法
总结:
1、学到了什么:
①:可以根据需求分析来解决问题。
②:对我在前八章Java程序设计基础上进行了一定量的复习。
③:能通过类间关系来降低代码的耦合性。
2、需要进一步改进的地方:
①:自主学习的能力,由于这门课程采用的是线上线下相结合的方式,通过老师指定
的方式或其他方式自学是很重要的。
②:编码时的调试能力,在pta作业的完成中,错误无可避免,但是要学会自己通过调
试来发现问题所在并解决它。
建议与意见:
无。