Java学习1-前三次题目集的分析与总结

发布时间 2023-03-26 11:16:07作者: JH2213

一.  前言

  作为刚学习JAVA的小白,以下只是本人作为普通学生,以当前能力和状态所做出的总结和分析,不足之处也欢迎各位大佬的指正!

  第一和第二次题目集的大部分题目难度较低,但是题量较大,主要考了JAVA的格式化输入输出、顺序结构、判断结构、循环结构、浮点运算、分支结构、字符串去重、字符串查找、普通数据查重、去除字符串中指定的部分、素数、字符串多字符分析、读题与分析、普通数据计算、字符串提取、几何形状的判定、JAVA方法的使用。

  第三次题目集的难度较前两次有部分提升,且更贴近JAVA的程序设计,但题量较少。主要考察了JAVA中类和方法的使用以及数据的分析处理。

二.代码的设计与分析

  因为题目较多,以下只选取部分题目进行分析总结

1.第一次题目集

  7-5 输入一个字符串,输出将其中重复出现的字符去掉后的字符串

 以下为源代码:

import java.util.Scanner;
public class Main{
    public static void main(String[] args){ 
        Scanner in =new Scanner(System.in);
        String zfc=in.nextLine();
        int n=zfc.length();    //记录字符串的长度
      char ch[]=zfc.toCharArray(); //将字符串转为字符数组
        int i,j,k;   //用于循环的变量
        for(i=0;i<n;i++){
            for(j=0;j<i;j++){
                if(ch[j]==ch[i]){ 
                    for(k=i+1;k<n;k++){
                        ch[k-1]=ch[k];    //发现重复元素则使数组向前缩进(再赋值)                  
                    }
                    i--;  //防止数组缩进后,检查发生遗漏的情况
                     n--; //使数组参与循环的长度减1
                }
            }
        }ch[n]='\0';//使字符数组有效长度减少(提前结束)
        System.out.println(ch);
    }
}

     刚开始接触Java还不会用String类。所以这道题我的思路是先把字符串转成字符数组,毕竟字符数组我还是比较熟悉。通过循环嵌套的方式,把当前元素与之前的元素比较,判断是否存在重复,如果存在重复就使后续数组中的元素向前缩进一个元素(本质是下标对应元素的再赋值)。然后再使循环元素i减一,因为如果不减一,下次判断查找会从缩进前下标为i+1的元素开始,遗漏原来下标为i的元素。再使数组长度n减一,这样数组参与循环的数组长度就会减一,最后再使字符数组ch[n]='\0';使字符数组内以字符串输出的有效长度减少,这样再进行输出,就会得到去重后的字符串。

  7-10 GPS数据处理。

读入一系列GPS输出,其中包含$GPRMC,也包含其他语句。在数据的最后,有一行单独的

END

表示数据的结束。

你的程序要从中找出$GPRMC语句,计算校验和,找出其中校验正确,并且字段2表示已定位的语句,从中计算出时间,换算成北京时间。一次数据中会包含多条$GPRMC语句,以最后一条语句得到的北京时间作为结果输出。

你的程序一定会读到一条有效的$GPRMC语句。

 以下为源代码:

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
      Scanner in=new Scanner(System.in);
        int l,i,r=0,j,m,n,e,f=0;
        double k=0.0;
        String p="END";//按题目要求设置结束字符串
        String shu=in.nextLine();
        int[] jian=new int[100];
        l=shu.length();//获得长度
        while(shu.compareTo(p)!=0){//判断是否输入结束
         r=0;k=0.0; char cun[]=shu.toCharArray();//把输进来的字符转字符数组
            if(shu.indexOf("GPRMC")!=-1){//查找“GPRMC”
                if(shu.indexOf('V')==-1){//查找题目中关键字符‘V’
                    i=shu.indexOf('$');i++;//indeXOF()查找字符为那个字符串的下标,所以还要再+1,才能使'$'到'*'的字符参与运算
                    for(;cun[i]!='*';i++){                      
                            r=r^cun[i];     //进行题目中的特殊运算             
                    }i++; //使下标指向后两位16进制数转成的字符
                    for(j=i;j<l;j++){      
                       if(cun[j]>='A'&&cun[j]<='F'){//判断16进制字符
                                if(cun[j]=='A')
                                    f=10;
                                if(cun[j]=='B')
                                    f=11;
                                if(cun[j]=='C')
                                    f=12;
                                if(cun[j]=='D')
                                    f=13;
                                if(cun[j]=='E')
                                    f=14;
                                if(cun[j]=='F')
                                    f=15;
                                 k+=Math.pow(16,l-j-1)*f; //有检测到16进制中的字母则进行该运算
                            }else{
                                k+=Math.pow(16,l-j-1)*(cun[j]-'0');//如果未检测到16进制数中的字母,则进行该运算
                            }  
                                        
                    }
                   r%=65536;//按照具体题目要求进行换算
                    if(r*1.0==k){   
                        m=shu.indexOf(',');n=shu.indexOf('.');//获取输入字符串中的UTC时间
                        String sc=shu.substring(m+1,n);
                        char shi[]=sc.toCharArray();//转为字符数组
                        e=sc.length();                
                        for(i=0;i<e;i++){
                            jian[i]=shi[i]-'0';//转为数字类型
                          
}jian[1]=jian[0]*10+jian[1];jian[1]+=8;//得到整数,并转为北京时间
                        if(jian[1]>24)//判断换算后是否超过24小时
                            jian[1]-=24;                             
                        }                                                                                         
                }
            }  
           shu=in.nextLine();//接受最后一行字符
            if(shu.compareTo(p)==0){      //判断是否输入了“END”
            if(jian[1]>=10){ //小时处不满10小时补0
       System.out.printf("%d:%d%d:%d%d\n",jian[1],jian[2],jian[3],jian[4],jian[5]);                     
                       }else{
       System.out.printf("0%d:%d%d:%d%d\n",jian[1],jian[2],jian[3],jian[4],jian[5]); 
      }     
            }
        }   
         }
}

  这一题是输入很多个很长的字符串,要求只提取特定的字符串中的数值,验证是否为特定字符串分几种方式,每个字符串还分很多段,每段之间用','隔开,做这道题时去了解了一些String类的方法,我的思路还是输入转成字符数组,感觉会更加方便判断,设定输入结束的字符串,用compareTo()来判断是否输入结束,然后根据几种判断特殊字符串的方式,通过indexOf()判断那些子字符串的位置,再依次进行判断,用if结构来判断后面16进制的两位字符是否包含16进制中代替数字的字母,再进行进制转换的相关计算。最后再转北京时间输出。

2.第二次题目集

  7-9 求下一天,输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。要求使用以下方法:

public static void main(String[] args);//主方法

public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型

public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值

public static void nextDate(int year,int month,int day) ; //求输入日期的下一天

  以下为源代码:

 

import java.util.Scanner;
public class Main{
    public static void main(String[] args){        //主方法
      Scanner in =new Scanner(System.in);
          int year,month,day;        
          year=in.nextInt();
          month=in.nextInt();
          day=in.nextInt();
          if(checkInputValidity(year,month,day)==true)
              System.out.println("Wrong Format");
          else {
              nextDate(year,month,day);
          }
    }
       public static boolean checkInputValidity(int year,int month,int day) { //判断输入日期是否合法
        int p=0;boolean p1=isLeapYear(year),p2=panduanmonth(month);   

if(year<1820||year>2020||month<1||month>12||day<1||day>31) p=1; if(p2==false){ if(p1==false&&month==2) { if(day>28) p=1; } if(p1==true&&month==2) { if(day>29) p=1; } if(month!=2) { if(day>30) p=1; } } if(p==1) return true; else return false; } public static boolean isLeapYear(int year) { //判断year是否为闰年 if(year%400==0&&year%4==0&&year%100!=0) { return true; }else { return false; } } public static boolean panduanmonth(int month) { //判断月份的天数是否为31天 int p=0;
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) { p=1; }else { p=0; } if(p==1) return true; else return false; } public static void nextDate(int year,int month,int day){ //计算并输出下一天 boolean p1=isLeapYear(year),p2=panduanmonth(month); if(month!=2) { //2月份最特殊,先判断是否为2月份 if(p2==true) {//不是二月的同时,判断是否为31天的月份 if(day==31) { if(month!=12) {//是31天的月份则接着判断是否为12月,后续基本就是这三个判断,然后有着对应的程序 day=1;month+=1; }else { year+=1;month=1;day=1; } }else { day+=1; } }else { if(day==30) { day=1;month+=1; }else { day+=1; } } }else { if(p1==true) {//是二月的同时是否为闰年 if(day==29) {//是闰年2月的同时,看是不是29号 month+=1;day=1; }else { day+=1; } }else{ if(day==28) {//是非闰年二月的同时,判断是否为28号 month+=1;day=1; }else { day+=1; } } } System.out.println("Next date is:"+year+"-"+month+"-"+day); } }

 

   这一题的思路主要是按照题目要求,写对应的方法,也是学习了一下Java的方法怎么自己写、自己用,感觉跟C语言差不多。为了方便,还另外写了一个方法,判断非2月月份的天数是否为31天。然后重点就是求计算并输出下一天的方法,换来换去发现还是要从最特殊的2月份的判断开始,这样才比较有逻辑性。是2月份就判断闰年,不是二月份就不用,但是要判断月份最大是否为第31天、是否为第12个月,然后再进行输出就行。

 

3.第三次题目集

 7-3 定义日期类——求下一天,定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。

以下为源代码:

import java.util.Scanner;
public class Main{
    public static void main(String [] args){
        Scanner in =new Scanner(System.in);
        int year,month,day; 
        year=in.nextInt();
        month=in.nextInt();
        day=in.nextInt();
        Date date=new Date();
        date.Date(year, month, day);    
        if(date.checkinputValidity()==false)  //判断日期输入是否正确
        System.out.println("Date Format is Wrong");
        else {
            date.getNextDate();
        }
    }
}
class Date{  //日期类
    private int year=0;
    private int month=0;
    private int day=0;
    private int[] mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};//每月的最大天数
    void Date(int year,int month,int day) { //有参输入
        setyear(year);
        setmonth(month);
        setDay(day);
    } 
    void setyear(int year) { //获取类内的year变量
        this.year=year; //使被赋值的year为类里的year
    }
    void setmonth(int month) {  //获取类内的month变量
        this.month=month;//使被赋值的month为类里的month
    }
    void setDay(int day) {  //获取类内的day变量
        this.day=day;    //使被赋值的day为类里的day
    }
    boolean checkinputValidity(){  //检查日期输入是否正确
        boolean judge=true; //设定判断用的boolean型变量
             int month,year,day;
month=getMonth();year=getYear();day=getDay();//获取类内所需日期变量
    if(year<1900||year>2000)
        judge=false;
    if(month<1||month>12)
        judge=false;
    else {
        if(month==2) {//以下为分情况判断day的输入是否正确
            if(isLeapYear(year)==true) {
              if(day<1||day>29)
                  judge=false;
            }else {
                if(day<1||day>28)
                      judge=false;
            }
        }else {
            if(day<1||day>mon_maxnum(month))
                judge=false;
        }
    }
    return judge;
    }
int getYear() {//返回类内year的值
        return year;
    }
    int getMonth() {//返回类内month的值
        return month;
    }
    int getDay() {//返回类内day的值
        return day;
    }
    boolean isLeapYear(int year){//判断是否为闰年
        boolean judge=false;
        if((year%4==0&&year%100!=0)||year%400==0)   
        judge=true;     
        return judge;
    }
    int mon_maxnum(int month) {//返回该月份的最大天数
        return mon_maxnum[month];
    }
    void getNextDate() { //计算并输出下一天
        int year,month,day,maxday;
        year=getYear();month=getMonth();day=getDay(); 
        maxday=mon_maxnum(month);
if(month==12) {//判断是否为12月
            if(day==maxday) {
                year++;month=1;day=1;
            }else {
                day++;
            }
        }else {
            if(month==2) {//判断是否为2月
                if(isLeapYear(year)==true) {
                    if(day==29) {
                        month++;day=1;
                    }else 
                        day++;                  
                }else {
                    if(day==28) {
                        month++;day=1;
                    }else
                        day++;
                }
            }else {
if(day==maxday) { //判断输入的day值是否与该月最大值相等
                    month++;day=1;
                }else
                    day++;
            }
        }
   System.out.printf("Next day is:%d-%d-%d",year,month,day);//格式化输出日期
    }
}

     本题与之前那道求下一天的题目类似,但是更贴近Java的编程习惯,采用类+方法的方式来书写。要写的类以及具体要求,题目给的图中已经写出,所以我的思路是先写类,学习了如何实现类后开始着手,定义、日期的变量设成private型,采用set······()来给类内的三个日期相关变量赋值,以get······()来获取三个日期变量的值,再将判断闰年、判断日期输入是否错误的方法放进类中,这次也有单独写一个方法来判断在传进来的月份下最大天数是多少,但是跟上次有很大不一样,上次是方法内通过if语句来判断,而这次是通过mon_maxnum数组来直接获取,方法内只需返回该值即可,当然闰年的2月份还是得单拎出来讨论。然后主方法就主动创建一个Date类,然后通过'.'的方式调用类里面的方法进行输入日期的判断和储存,最后也是用类里的求下一天的方法输出最后结果即可。

圈复杂度:

 

 类图:

   7-4 日期类设计,设计一个类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”格式返回日期值

 

应用程序共测试三个功能:

 

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

 

主方法已给出。

以下为源代码:

 

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;
        int choice = input.nextInt();//根据choice的值来判断要使用什么功能
        if (choice == 1) { 
            int m = 0;
            year = Integer.parseInt(input.next()); 
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
            DateUtil date = new DateUtil(year, month, day);//设立一个DateUtil对象
            if (!date.checkInputValidity()) { //判断输入是否正确
                System.out.println("Wrong Format");
                System.exit(0);
}
            m = input.nextInt(); 
            if (m < 0) {  
                System.out.println("Wrong Format");
                System.exit(0);
            }
            System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { 
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
            DateUtil date = new DateUtil(year, month, day);
            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);            
}
            n = input.nextInt();
            if (n < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
            System.out.println(date.getPreviousNDays(n).showDate());
        } else if (choice == 3) {    
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());
            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());
            DateUtil fromDate = new DateUtil(year, month, day);//新建两个对象来存储两个日期
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
           System.out.println("The days between " + fromDate.showDate() +  " and " + toDate.showDate() + " are:"  + fromDate.getDaysofDates(toDate));
            } else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        }
        else{
System.out.println("Wrong Format");
            System.exit(0);
        }        
    }
}
class DateUtil{
    private long year=0;
    private long month=0;
    private long day=0;
    private long[] mon_maxnum=new long[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
    public DateUtil(long year, long month, long day) {//有参输入
        setyear(year);
        setmonth(month);
        setDay(day);
    }
    void setyear(long year) {//给对象里的year赋值
        this.year=year;
    }
    void setmonth(long month) {//给对象里的month赋值
        this.month=month;
    }
    void setDay(long day) {//给对象里的day赋值
        this.day=day;
    }
    public boolean checkInputValidity(){//判断是否输入正确
        boolean judge=true;
             long month,year,day;
    month=getMonth();year=getYear();day=getDay();
    if(year<1820||year>2020)
        judge=false;
    if(month<1||month>12)
        judge=false;
    else {
        if(month==2) {
if(isLeapYear(year)==true) {
              if(day<1||day>29)
                  judge=false;
            }else {
                if(day<1||day>28)
                      judge=false;
            }
        }else {
            if(day<1||day>mon_maxnum(month))
                judge=false;
        }
    }
    return judge;
    }
    long getYear() {//获取对象里的year值
        return year;
    }
    long getMonth() {//获取对象的month值
        return month;
    }
    long getDay() {//获取对象的day值
        return day;
    }
    public boolean isLeapYear(long year){//判断是否为闰年
        boolean judge=false;
        if((year%4==0&&year%100!=0)||year%400==0)   
        judge=true;     
        return judge;
    }
    long mon_maxnum(long month) {
        return mon_maxnum[(int)month];
    }
public DateUtil getPreviousNDays(int n) { //获取前n天的日期
        long year,month,day,maxday;
        year=getYear();month=getMonth();day=getDay(); 
        long minusyear=n/365;//先把n中整年的天数提出来,提高代码效率
        long leavedays=n%365;  //求剩余不满一年的天数 
        if(n<100000){//如果n不是很大就按如下方法计算日期
          for(int i=1;i<minusyear;i++) {
            if(isLeapYear(year-i)==true) {
                leavedays--;         //每有一次闰年,之前从n天中提出去的整年的天数就要+1,相对的剩余天数减一 ,因为提整年除的是365      
            }
        }year-=minusyear;  //将提出来的年数用原来的年份减去
        }else leavedays=n;//如果n很大就一天一天的加
        
        while(leavedays>0) {//只要还有剩余天数就一直做如下程序
        
            if(month==3) {//判断输入的月份是否为3月,因为减去输入的day后就是2月
            if(isLeapYear(year)==true) {
                if(leavedays-day>=0) {
                leavedays=leavedays-day;month--;day=mon_maxnum(month)+1;
                }else {
                    day-=leavedays;//不满输入的day数,就直接减
                  }
                }else {
                if(leavedays-day>=0) {//与上方同理
                    leavedays=leavedays-day;month--;day=mon_maxnum(month);
                    }else {
                        day-=leavedays;
                         }
                }
            }else {
                if(month==1) {//同理减完day后变为12月
                    if(leavedays-day>=0) {
                        leavedays=leavedays-day;month=12;day=mon_maxnum(month);year--;
                    }else
               day-=leavedays;    //与month==3的if语句类似
                }else {
                    if(leavedays-day>=0) {
                        leavedays=leavedays-day;month--;day=mon_maxnum(month);
                        }else {
                            day-=leavedays;leavedays=0;
                          }
                }
            }
        
        }     
        return new DateUtil(year,month,day);
    }
    public String showDate() {
        String year=String.valueOf(getYear());
        String month=String.valueOf(getMonth());
        String day=String.valueOf(getDay());
        String result=year+"-"+month+"-"+day;
        return result;
    }
    public DateUtil getNextNDays(int n) {//获得下n天的日期
        long year,month,day,maxday;
        year=getYear();month=getMonth();day=getDay(); 
        long addyear=n/365;
        long leavedays=n%365;
        if(leavedays>0)
            leavedays+=day;//按原来day为0算,故要加上day
        if(n<1000000) {//与获得前n天的日期同理
            for(long i=1;i<addyear;i++) {
                if(isLeapYear(year+i)==true) {
                    leavedays--;                
}
            }year+=addyear;
            if(month>2&&addyear!=0) {
                if(isLeapYear(year)==true)
                    leavedays--;
            }
        }else {
            leavedays=n+day;
        }
        
        while(leavedays>0) {//剩余天数不为0就继续
            maxday=mon_maxnum(month);
            if(month==2) {
            if(isLeapYear(year)==true) {
                if(leavedays-maxday-1>=0) {
                leavedays=leavedays-maxday-1;month++;day=1;
                }else {
                    day+=(leavedays-1);leavedays=0;//减1是因为按数值上其实上一步变化后的day应为0,但日期没有第0天,所以改为赋值为1,计算时要减去
                  }
                }else {
                    if(leavedays-maxday>=0) {
                        leavedays=leavedays-maxday;month++;day=1;
                        }else {
                            day+=(leavedays-1);leavedays=0;//同上
                          }
                }
            }else {
                if(month==12) {
                    if(leavedays-maxday+day>=0) {
                        leavedays=leavedays-maxday;month=1;day=1;year++;
                    }else {
                        day+=(leavedays-1);leavedays=0;
                    }
                }else {
if(leavedays-maxday>=0) {
                        leavedays=leavedays-maxday;month++;day=1;
                        }else {
                            day+=(leavedays-1);leavedays=0;
                          }
                }
            }
        
        }
            
        return new DateUtil(year,month,day);//返回DateUtil对象
    }
    public long getDaysofDates(DateUtil date) {//输出相差了几天
        long yearnumber=Math.abs(date.getYear()-year);//求年数相差的绝对值
    
        long daynumber=Math.abs(date.getDay()-day);//求天数相差的绝对值
        long resultday=yearnumber*365;//把相隔的年数乘365得出天数
        if(date.getYear()-year<0) {     //如果输入的年份早于对象中的
            for(int i=0;i<yearnumber;i++) {     
                    if(isLeapYear(date.getYear()+i)==true) {
                        resultday++;//每有一个闰年,天数+1
                    }
                }
            if(date.getMonth()<=2) {//判断对象的month是否小于2月
                for(int i=1;i<date.getMonth();i++) {                    
                    resultday-=mon_maxnum(i);
                }
                resultday-=date.getDay();
            }else {
for(int i=1;i<date.getMonth();i++) {
                    if(i!=2)
                    resultday-=mon_maxnum(i);
                    else {
                        if(isLeapYear(year)==true) {
                            resultday-=mon_maxnum(i)-1;//因为该数组2月对应的最大天数为28天
                        }else resultday-=mon_maxnum(i);
                    }
                }
                resultday-=date.getDay();
            }
            for(int i=1;i<month;i++) {//计算最后隔了多少个月
                if(i!=2)
                resultday+=mon_maxnum(i);
                else {
                    if(isLeapYear(year)==true) {
                        resultday+=(mon_maxnum(i)+1);
                    }else resultday+=mon_maxnum(i);
                }
            }
            resultday+=day;
        }
        if(date.getYear()-year==0){//如果同年同月怎么计算
            if(date.getMonth()-month<=0) {
                for(long i=date.getMonth();i<month;i++) {
                    if(i==2) {
                        if(isLeapYear(year)==true) {
                            resultday+=(mon_maxnum(i)+1);
                        }else resultday+=mon_maxnum(i);
                    }else
                     resultday+=mon_maxnum(i);
                }resultday+=daynumber;          
            }else {
                for(long i=month;i<date.getMonth();i++) {
if(i==2) {
                        if(isLeapYear(year)==true) {
                            resultday+=(mon_maxnum(i)+1);
                        }else resultday+=mon_maxnum(i);
                    }else
                     resultday+=mon_maxnum(i);
                }resultday+=daynumber;          
            }
            
        }
        if(date.getYear()-year>0) {//如果输入的年份晚于对象中的
            for(int i=0;i<yearnumber;i++) {     //以下与上面代码前面类似
                if(isLeapYear(year+i)==true) {
                    resultday++;
                }
            }
            if(month<=2) {
                for(int i=1;i<month;i++) {                  
                    resultday-=mon_maxnum(i);
                }
                resultday-=day;
            }else {
                for(int i=1;i<month;i++) {
                    if(i!=2)
                    resultday-=mon_maxnum(i);
                    else {
                        if(isLeapYear(year)==true) {
                            resultday-=mon_maxnum(i)-1;
                        }else resultday-=mon_maxnum(i);
}
                }
                resultday-=day;
            }
            for(int i=1;i<date.getMonth();i++) {
                if(i!=2)
                resultday+=mon_maxnum(i);
                else {
                    if(isLeapYear(date.getYear())==true) {
                        resultday+=(mon_maxnum(i)+1);
                    }else resultday+=mon_maxnum(i);
                }
            }
            resultday+=date.getDay();
            
    }
        return resultday;
}
    public boolean equalTwoDates(DateUtil date) {//比较两个日期是否相等
        if(date.getDay()==day&&date.getMonth()==month&&date.getYear()==year) {
            return true;
        }else 
            return false;
    }
    public boolean compareDates(DateUtil date) {//比较两个日期谁更早
        int judge=0;
        if(year<date.getYear()) {
            judge=1;
        }if(year>date.getYear()) {
            judge=2;
        }
        if(judge==0) {
            if(month<date.getMonth()) {
                judge=1;
}
            if(month>date.getMonth()) {
                judge=2;
            }       
            if(judge==0) {
                if(day<date.getDay()) {
                    judge=1;
                }
                if(day>date.getDay()) {
                    judge=2;
                }   
            }
        }
        if(judge==1) {
            return true;
        }
        if(judge==2||judge==0) {
            return false;
        }
        return false;
        
    }
}

 

     我的思路是:因为主方法已给出,所以需要根据主方法来写类,其它必要的方法也都在题目内给出,除了三个方法,其它方法都跟前面求日期的题目差不多。第一个是求下n天的日期,在n不是很大的时候,先除365看看隔了几年,再加上现在对象的年份求出大致最终年份,然后用循环判断闰年,每有一个闰年提出年份后的剩余天数-1+上对象的day数,再把对象天数当做0,然后整月整月的加,每个月的最大天数,那个mon_maxnum数里有,只需注意闰年二月和12月更新年份,最容易忽略的点是:因为day没有第0天,所以在加一个月后,会给day赋值为1,在最后剩余天数不足一个月时,就得把天数直接加到day上,此时要把之前赋值给day的1减掉,否则会多一天,因为在计算中实际上那个时候day=0。当n很大时,可能因为闰年的关系,实际给对象加的年数是小于算出来的值的,这时候就直接整月整月的加,来避免错误;第二个是求前n天的日期,与求下n天日期差不多,只不过加变成减,有一个不同的地方就是无需在最后天数不满一个月时减一,因为最后是用30或31去减,不会多余;第三个是求两日期间隔天数

圈复杂度:

 

 类图:

三.遇到的问题与解决后的心得

1.第一次题目集

7-5

 遇到了重复元素只去掉了一部分的情况,在数组缩进后加上i--;。缩进后数组内元素发生了位置变化,这个很容易遗漏,需注意。

7-10

 忽略了indexOf()查找字符获得的下标是该字符的下标的事实,忘记将下标再往后移一个单位。这种字符下标搞错的情况还是很容易发生的,写着写着就漏了再移一位,写代码时还是要把下标、变量的值记明白,想清楚,这样才能更好地运用。在该方法后加上i++;即可。

2.第二次题目集

7-9

 

 忘记在月份更新时给day再赋值为1,导致了日期显示day为0的情况,日期没有第0天,这个被我忽略了,还是得仔细想想输出的格式中所内含的一些东西。在月份更新处加个day=1;即可。

3.第三次题目集

7-3

未发生错误

7-4

1)求下n天,当n很大时会出错,因为在从n中取整年的天数时是默认都是365天一年,后续再通过循环来加上闰年缺失的那部分,这种方法在取完整年,整年中闰年的个数少于剩余天数时才有效,不然就会错误,剩余天数出现负值,整年取的偏大,后续是通过加判断,使n很大时直接采用整月整月加的方式计算才解决。这个错误提醒了我在设计程序的时候要多多考虑其适用范围,免得出现不在适用范围内而导致出错的情况,以下为正确结果:

 

2)求前n天

 

除了上述同样的问题以外,还有忽略了当前年份为闰年,而当前月份大与2时的多出的那一天。因为采取先减整年的方式,所以会出现减完年份后为平年,而初始为闰年的情况,导致最后结果多减了一天,比如上面图片中结果就应该是2-28,对于数据变化的初始状态和末尾状态的关注还是不够,所以才会犯这种错误。在减年份之前多加一个嵌套判断语句看是不是初始月份超过2月,初始年份是否为闰年就可以了。

3)求两日期间隔天数

 

忽视了两日期同年或同月的情况,导致答案错误。我对于数据变化的情况还是想的不够全面,漏了这种情况,之后做题还是要更加仔细的思考。加上相关判断语句和相关程序,改为从月份开始比较,进行计算,对于也同月的则从天数开始计算,就可以改正错误。以下为正确结果:

 

四.代码优化的想法

    刚开始学Java,代码风格还是偏向c语言,套用的c语言的模式,也没用到什么Java的语法和结构,像第一二题目集的例子中将字符串转为字符数组,其实大可不必,直接用String类的方法就可以解决问题,然后对类以及方法的设计和使用还不够熟练,应该多用用,使每个方法实现单一功能。代码中为求简单,我的变量、方法、数组之类的命名都是直接用字母或拼音缩写,导致可读性不高,以后得多多注意,多用英文来命名。还有就是在PTA提交的源码没有注释,也导致了可读性下降,后续我会写一些,保持良好习惯。

五.学习总结和对现有学习模式的建议

 目前的自己的Java学习进度还是太慢了,一方面是有很多其它的事,导致时间被挤占,另一方面则是自己学习效率确实是偏低,目前自己只学会了很基本的Java语法和一些类的方法。以后还是得加强时间管理,增加学习Java的时间,多多与同学沟通,增加自己的学习效率。对于老师上课重点提到的方法和类得加强自学,对于已知的方法和类还要增加熟练度,平时多看看相关的书,增加自己对面向对象的理解,体会类的设计。对于现有教学模式感觉还可以,也才刚开始几周,目前也没什么意见和建议。

  以上就是我对Java学习第一阶段的三次题目集和当前学习的小小总结。