CZD的第一次Blog作业

发布时间 2023-03-26 17:38:48作者: czdczd

前三次PTA作业总结:

 


 

(1).前言

  第一次作业:

     知识点:考察java的输入与输出,以及循环的使用,和一些简单函数的调用。

     题量:12道题。

     难度:较为简单

  第二次作业:

     知识点:考察java的输入与输出,以及循环的使用,和一些简单函数的调用,和一些简单类的定义和使用。

     题量:9道题

     难度:前8道题目较为简单,第九道题较为复杂

  第三次作业

    知识点:java的基本语法实现,定义和设计新的类以及定义属性和方法。

    题量:4道题

    难度:1 2 题较为简单,3 4 题稍微复杂。

    


 

(2).设计与分析

      题目集(3):

         7-3:

             需求分析:本题需设计一个Date类,类中有基本属性和getter和setter,还主要有计算下一天的方法,其他判断是否是闰年以及输入日期是否合法的方法也应在其中。当输入非法时,输出指定语句;当输入合法时,按指定格式输出结果。

             类图分析:如图:

   

     类图说明:year、month、day的getter和setter分别为获取和改变当前属性的方法,isLeapYear为判断是否为闰年的方法,checkInputValidity为判断当前输入日期是否合法,getNextDate为获取输入日期的下一天的方法。

  心得:第一次使用powerdesigher画类图,还不是很熟练,还有很多需要学习的东西;

 

全部代码:

 

  1 import java.util.Scanner;
  2 public class Main{
  3     int day;
  4     int month;
  5     int year;
  6  public static void main(String[] args){
  7      
  8      Scanner input = new Scanner(System.in);
  9       Date t= new Date();
 10         int year = input.nextInt();
 11         t.setYear(year);
 12         int month = input.nextInt();
 13         t.setMonth(month);
 14         int day = input.nextInt();
 15         t.setDay(day);
 16      if(t.checkInputValidity(year,month,day)==true){
 17          t.getNextDate();
 18          System.out.println("Next day is:"+t.getYear()+"-"+t.getMonth()+"-"+t.getDay());
 19      }else{
 20          System.out.println("Date Format is Wrong");
 21      }
 22  }
 23 }
 24 
 25 class Date{
 26     private int year;
 27     private int month;
 28     private int day;
 29     int[] mon_maximum = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
 30     Date(){
 31              this.day = day;
 32              this.month = month;
 33              this.year = year;
 34             }
 35     public int getYear(){
 36         return year;
 37     }
 38     public void setYear(int year){
 39          this.year = year;
 40     }
 41     public int getMonth(){
 42         return month;
 43     }
 44     public void setMonth(int month){
 45         this.month = month;
 46     }
 47     public int getDay(){
 48         return day;
 49     }
 50     public void setDay(int day){
 51         this.day = day;
 52     }
 53     public boolean isLeapYear(int year){
 54       if(year%400==0||year%4==0&&year%100!=0){
 55           return true;
 56       }else return false;
 57     }
 58     public boolean checkInputValidity(int year, int month, int day){
 59         if(year>=1900&&year<=2000&&month>=1&&month<=12&&day>=1&&day<=31)
 60     {
 61         if(month==2){
 62             if(isLeapYear(year)==true){
 63                 if(day<=29) return true;
 64                 else return false;
 65             }else{
 66                 if(day<=28) return true;
 67                 else return false;
 68             }
 69         }else if(month==4||month==6||month==9||month==11){
 70             if(day<=30) return true;
 71             else return false;
 72         }else return true;
 73 
 74     }else return false;
 75     }
 76     
 77     
 78     public void getNextDate(){
 79         if(month==12){
 80          if (day <= 30)
 81            this.day = day++;
 82          else {
 83             this.year = ++year;
 84             this.month = 1;
 85             this.day = 1;
 86      }}else if(month==1||month==3||month==5||month==7||month==8||month==10){
 87         if(day>=1&&day<=30){
 88             this.day=day++;
 89 
 90         }else if(day==31){
 91             this.day=1;
 92             this.month=++month;
 93         }
 94      }else if(month==4||month==6||month==9||month==11){
 95          if(day>=1&&day<=29){
 96             this.day=++day;
 97       
 98         }else if(day==30){
 99             this.month=month++;
100             this.day=1;
101             
102         }
103      }else if(month == 2){   
104              if(isLeapYear(year)==true){
105           if(day>=1&&day<=28){
106             this.day=++day;
107             
108         }else if(day==29){
109             this.day=1;
110             this.month=++month;
111           
112         }
113         }else{
114          if(day>=1&&day<=27){
115             this.day=++day;
116         }else if(day==28){
117             this.day=1;
118             this.month=++month;
119         }
120     }
121  }
122 }
123 }
124 
125 
126    

 

      源码分析:主函数中主要是日期的输入和输出,Date类中有私有整型属性year、month、day,有基本属性的getter和setter方法:对本地变量进行赋值和返回实现;isLeapYear(int year):判断输入的年份是否能被四整除而不能被一百整除或能否被四百整除;checkInputValidity():判断年份是否在题干所给范围内,月份是否在1到12中,其中还需要对2月进行讨论,判断是否为闰年,闰年2月为29,平年2月为28天;getNextYear():分大月和小月和2月分别计算,在算2月的下一天是还要注意是否为闰年,即判断条件不同。本题难度不大,但源码中有些部分过于冗余显得格格不入,望日后能更好的改进!

 


Most Complex Methods in 2 Class(es)  Complexity Statements  Max Depth Calls
Date.checkInputValidity()  19 21 
Date.Date()   1  0
Date.getDay()  1  1  2
Date.getMonth()  1  0
Date.getYear()  1  1  2
Date.isLeapYear()  5  4  3
Date.setDay()   1  1  2  0
Date.setMonth()  1  1
 Date.setYear()  1  1
 Main.main()   3 13  10 

 

 

 

 

 

 

         7-4:

              需求分析:

                        1. 设计一个类DateUtil类,该类含有三个私有整型属性year、month、day
                        2.创建该类的构造方法、属性的getter及setter方法
                        3.编写一个方法,检测输入的年、月、日是否合法
                        4.编写一个方法,判断year是否为闰年
                        5.编写一个方法,求year-month-day的下n天日期
                        6.编写一个方法 , 取得year-month-day的前n天日期
                        7.编写一个方法,比较当前日期与date的大小(先后)
                        8.编写一个方法,判断两个日期是否相等
                        9.编写一个方法, 求当前日期与date之间相差的天数
                       10.编写一个方法,  “year-month-day”格式返回日期值

     

        类图:

 

 

 

 

 

 

      类图说明:本题其实就是上一题的迭代版本,从上一题求下一天的日期到这一题求下n天和前n天可以看出,基本属性一样,基本的getter和setter方法一样,不同的是这题增加了一些方法,如compareDates()等。

     

 

源码:

  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 
 85 
 86 
 87 
 88 
 89 class DateUtil{
 90     private int year;
 91     private int month;
 92     private int day;
 93     public int[] m = {0,31,28,31,30,31,30,31,31,30,31,30,31};
 94     
 95     public DateUtil(DateUtil d){
 96         this.day = d.getDay();
 97         this.month = d.getMonth();
 98         this.year = d.getYear();
 99 
100     }
101     
102     public DateUtil(int y, int m, int d){
103         year = y;
104         month = m;
105         day = d;
106     }
107 
108 
109 
110     public int getYear(){
111         return year;
112     }
113     public int getMonth(){
114         return month;
115     }
116     public int getDay(){
117         return day;
118     }
119     
120     public void setYear(int year){
121         this.year = year;
122     }
123     public void setMonth(int month){
124         this.month = month;
125     }
126     public void setDay(int day){
127         this.day = day;
128     }
129     
130     public boolean checkInputValidity()//检测输入的年、月、日是否合法
131     {
132          if(year<1820||year>2020||month<1||month>12)
133              return false;
134          if(this.isLeapYear(this.getYear())){
135              if(month==2){
136                  if(day<1||day>29)
137                      return false;
138              }
139              
140          }else{
141              if(day<1||day>this.m[month])
142                  return false;
143          }
144         return true;
145     }
146     
147     public boolean isLeapYear(int year)//判断year是否为闰年
148     {
149       if(year%400==0||year%4==0&&year%100!=0){
150           return true;
151       }else return false;
152     }
153     
154     
155     public DateUtil getNextNDays(int n)//取得year-month-day的下n天日期
156     {
157         while(n>365){
158             if(this.isLeapYear(this.getYear())&&this.getMonth()<=2){
159                 if(this.getMonth()==2&&this.getDay()==29){
160                     this.setMonth(3);
161                     this.setDay(1);
162                 }
163                 this.setYear(this.getYear()+1);
164                 n-=366;
165             }else if(this.isLeapYear(this.getYear()+1)&&this.getMonth()>2){
166                 this.setYear(this.getYear()+1);
167                 n-=366;
168             }else{
169                 this.setYear(this.getYear()+1);
170                 n-=365;
171             }
172         }
173         for(int i=0;i<n;i++)
174         {
175             this.setDay(this.getDay()+1);
176             if(this.isLeapYear(this.getYear())&&this.getMonth()==2){
177                 if(this.getDay()>29){
178                     this.setMonth(3);
179                     this.setDay(1);
180                 }
181             }else if(this.getDay()>this.m[this.getMonth()]){
182                 this.setMonth(this.getMonth()+1);
183                 this.setDay(1);
184             }
185         }
186         return this;
187     }
188     
189     public DateUtil getPreviousNDays(int n)//取得year-month-day的前n天日期
190      {
191        while(n>365){
192             if(this.isLeapYear(this.getYear())&&this.getMonth()>2){
193                 this.setYear(this.getYear()-1);
194                 n-=366;
195             }else if(this.isLeapYear(this.getYear()-1)&&this.getMonth()<=2){
196                 this.setYear(this.getYear()-1);
197                 n-=366;
198             }else{
199                 this.setYear(this.getYear()-1);
200                 n-=365;
201             }
202        }
203     
204         
205         for(int i=0;i<n;i++)
206         {
207             this.setDay(this.getDay()-1);
208            if(this.getDay()<=0){
209                this.setMonth(this.getMonth()-1);
210                if(this.getMonth()<=0){
211                    this.setMonth(12);
212                    this.setYear(this.getYear()-1);
213                }
214                if(isLeapYear(this.getYear())&&this.getMonth()==2){
215                    this.setDay(29);
216                }else{
217                    this.setDay(this.m[this.getMonth()]);
218                }
219            }
220         }
221         return this;
222     }
223     
224         
225     public boolean compareDates(DateUtil date)//比较当前日期与date的大小(先后)
226     {
227          if(this.year > date.getYear())
228             return true;
229         else if(this.year == date.getYear() && this.month > date.getMonth())
230             return true;
231         else if(this.year == date.getYear() && this.month == date.getMonth() && this.day > date.getDay())
232             return true;
233         return false;
234 
235     }
236         
237         
238     public boolean equalTwoDates(DateUtil date)//判断两个日期是否相等
239     {
240         if(this.year != date.getYear())
241             return false;
242         else if(this.day != date.getDay())
243             return false;
244         else if(this.month != date.getMonth())
245             return false;
246         else
247             return true;
248 
249     }
250         
251         
252     public int getDaysofDates(DateUtil date)//求当前日期与date之间相差的天数
253     {
254         int cnt1=0;
255         int cnt2=0;
256         for(int i=1;i<this.getYear();i++)
257         {
258             if(this.isLeapYear(i)){
259                 cnt1+=366;
260             }else cnt1+=365;
261         }
262         for(int i=1;i<this.getMonth();i++){
263             if(this.isLeapYear(this.getYear())&&i==2){
264                 cnt1+=29;
265             }else cnt1+=this.m[i];
266         }
267         cnt1=cnt1+this.getDay();
268         
269         for(int i=1;i<date.getYear();i++)
270         {
271             if(date.isLeapYear(i)){
272                 cnt2+=366;
273             }else cnt2+=365;
274         }
275         for(int i=1;i<date.getMonth();i++){
276             if(date.isLeapYear(date.getYear())&&i==2){
277                 cnt2+=29;
278             }else cnt2+=date.m[i];
279         }
280         cnt2=cnt2+date.getDay();
281         return(Math.abs(cnt1-cnt2));
282     }
283        
284     
285     
286     
287     public String showDate()//以“year-month-day”格式返回日期值
288     {
289         return(year+"-"+month+"-"+day);
290     }
291     
292     
293 
294 }

 

 

    源码分析:

Most Complex Methods in 2 Class(es)  Complexity Statements  Max Depth Calls
DateUtil.checkInputValidity() 7 10 4 2
DateUtil.compareDates() 7 7 2 6
DateUtil.DateUtil() 1 3 2 0
DateUtil.DateUtil() 1 3 2 3
DateUtil.equalTwoDates() 5 8 2 3
DateUtil.getDay() 1 1 2 0
DateUtil.getDaysofDates() 15 25 4 11
DateUtil.getMonth() 1 1 2 0
DateUtil.getNextNDays()  14 23 5 24
DateUtil.getPreviousNDays() 13 22 5 20
DateUtil.getYear() 1 1 2 0
DateUtil.isLeapYear() 5 4 3 0
DateUtil.setDay() 1 1 2 0
DateUtil.setMonth() 1 1 2 0
DateUtil.setYear() 1 1 2 0
DateUtil.showDate() 1 1 2 0

 

                                             

 

 

 

       


 

(3).踩坑心得

     7-3中的:

 

 

错误:进行编写java代码时语言逻辑错误,格式不规范导致直接编译错误

 

 

 

错误:写代码时思考不全面,导致部分情况错误,严重的可能会导致全盘错误

 

   7-4中:

 


 

 

 

 

 错误:对类中的方法引用方法不正确,即对方法的理解不到位,直接导致编译错误


 

错误:变量在定义时未对齐进行赋初值,而后面直接对其进行引用


 

 

错误:程序里多层循环导致超时,所以写程序时应先画流程图构思,写一步想一步只会导致写出的代码没有条理,虽然可能自己看的懂,但别人看不懂的就是垃圾代码!

 


错误与心得总结:在三次PTA作业中,写代码时都存在一个共同的问题就是格式不规范,直接导致写出来的代码看起来毫无逻辑关系,而且后期修改也比较困难,还有就是自己写的代码并没有注释,这导致代码写的很乱只有自己看的懂,换做他人就看不懂了,纯纯垃圾代码一堆,对类中方法的调用还是不熟悉,导致程序在编译时出错,还有就是在写代码的时候,写代码之前应该在构思好一个整体,这样程序才会有逻辑和条理,要有大局观,这对以后工作总归是好的!


 

(4).改进建议

    在第三次作业中的7-3中:

 

 

此处求输入日期的下一天时,用的是一个一个月份去判断31天还是30天以及闰年二月和平年二月的区别,这样不仅种类多容易错误,而且多个循环还很容易导致超时,所以在由7-3迭代而来的7-4中便采用了不同的方法,即把全年月份的最多天数都放在一个数组当中,除了闰年二月有却别之外其他月份均可以直接用数组中的元素来判断,如下图:

 

 

 

其中的this.getDay()>this.m[this.getMonth()]便是采用了改进的方法,使得程序变得更加简单易懂,运行时间也会大大减少。

 

 以及在7-4中:

 

求日期差的时候,我用的方法是先分别求出两个输入日期的总天数然后在对其作差并取绝对值,这样其实是走了捷径,没有用到判断两日期先后的方法,这点在后续迭代中可以做到可持续改进。

 


 

(5).总结

        对于初学java的这一阶段的三次PTA作业,受益匪浅,主要学会了java的基本语法输入输出,以及定义新的类和按要求编写方法,对库函数的调用,数组的定义和使用;当然,自身暴露出来的问题也很多,例如:编程时的规范性还不够,这是后期学习需要加强的,某些语法使用时还不规范会导致编译错误,在后期学习中,还需要系统学习语法,零碎化的学习语法导致知识构架不完整,使用的时候固然就不会联想。在后期学习中,也要加强写代码时的独立性,减少对他人的依赖性,为以后的工作环境打基础;此外,其实打字还很慢,打字还需要多练练,加快码字速度!