PTA OOP训练集1-3总结Blog

目录

一、前言

二、设计与分析

三、踩坑心得

四、改进建议

五、总结

一、前言

  这个学期学习了Java,Java和上个学期学习的C语言有很大的不同,C语言是面向过程的语言,而Java是面向过程的语言,在学习过程中,我也学习到了java关于类、方法之类的概念,Java拥有许多强大的方法可以很便利地解决一些c语言难以实现的问题,但学习难度比C要大得多,从开学到现在,我一共写了3次pta上的编程练习,从题量上来看,第一次训练集是12题,第二次训练集是9题,第三次训练集是4题。而从难度上来说,第二次训练集最简单,其次是第一次训练集,第三次训练集最难。从知识的覆盖面来说,第一次主要是锻炼我们像循环、判断、字符串处理等等比较基础的语法,第二次训练集大部分也都是和第一题比较相似的题型,而第三次题目集则是注重于类和方法的构造要规范,符合如迪米特法则,单一职责原则等一样的原则。

二、设计与分析

(1)第一次题目集的第八题:

     

从一个字符串中移除包含在另一个字符串中的字符。输入两行字符串,将第一行字符串中包括第二行字符串中的所有字母去除。输出去除后保留的字符串。

输入格式:

第一行输入一个字符串
第二行输入一个字符串

输出格式:

输出移除后的字符串

输入样例:

在这里给出一组输入。例如:

abcdefghijklmnopqrstuvwxyz
secret
 

输出样例:

在这里给出相应的输出。例如:

abdfghijklmnopquvwxyz
 
 
 

  这个题目看起来简单,但是因为我一开始并没有接触过Java中操作字符串的方法,于是我去菜鸟教程查找教程,一开始使用的是String类来写的,但是发现String类功能不够完善,而菜鸟教程下有一个

所以我使用了StringBuffer类来写。

  本题思路是:一开始在str1前添加一个特殊字符,防止出现类似数组超限一样的错误,然后输入两个字符串(注意这里要使用可以输入空格符的nextLine方法),通过嵌套循环对两个字符串的每一个字符都进行一次判断,如果相同就去除str1中相应的字符。同时因为少了一个字符,循环的条件 i 也应该减1,避免出现字符的遗漏。

 

代码清单如下:

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        StringBuilder str1 = new StringBuilder();
        StringBuilder str2 = new StringBuilder();
        str1.append(")");                           //在数组前添加一个空白字符
        str1.append(input.nextLine());
        str2.append(input.nextLine());
        for(int i = 0;i<str1.length();i++){         //遍历第一个字符串
            for(int j = 0;j<str2.length();j++){     //遍历第二个字符串
                if(str1.charAt(i)==str2.charAt(j)){ //如果有字符相等
                    str1.deleteCharAt(i);           //删除字符
                    i--;                            //i退一位,防止出现遗漏
                    j = 0;                          //重新开始查重
                }
            }
        }
        str1.deleteCharAt(0);                       //删除开头空格符号
        System.out.print(str1);
    }
}

 

 (1)第二次题目集的第八题。

 

输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
注意:不允许使用Java中和日期相关的类和方法。

要求:Main类中必须含有如下方法,签名如下:

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) ; //求输入日期的下一天
 
 

输入格式:

在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。

输出格式:

    1. 当输入数据非法及输入日期不存在时,输出“Wrong Format”;
    2. 当输入日期合法,输出下一天,格式如下:Next date is:年-月-日

输入样例1:

在这里给出一组输入。例如:

2020 3 10
 

输出样例1:

在这里给出相应的输出。例如:

Next date is:2020-3-11
 
 

    这个题目总的来说比较简单,题目所给判断三角形的顺序也是按照最特殊到最普通的顺序来排列的,所以我们只需要按照题目所给的思路依次判断就可以解决问题,但是有一个问题:等腰直角三角形的判断总是出现错误, 多次测试后发现原因在于Java程序无法做到精确的计算,使用那些数学函数都只能达到近似的效果,但是做判断是这一点的误差却会被判断为不相等,所以我想到了使用float强制转换把小数点后面的误差给消除,从而可以进行判断为等腰直角三角形。

 

代码清单如下:

 import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        double l1 = input.nextDouble();
        double l2 = input.nextDouble();
        double l3 = input.nextDouble();
        
        if(l1<1 || l2<1 ||l3<1 || l1>200 || l2>200 ||l3>200)
            System.out.println("Wrong Format");
        else if(l1 + l2 <=l3 || l1 + l3 <= l2|| l2 + l3 <=l1)//是否可以构成三角形
            System.out.println("Not a triangle");
        else if(l1==l2 && l2==l3)//是否是等边三角形
            System.out.println("Equilateral triangle");
        else if(l1 == l2&&(float)(l1*l1+l2*l2)==(float)(l3*l3) || l3 == l2&&(float)(l3*l3+l2*l2)==l1*l1 || l1 == l3&&(float)(l1*l1+l3*l3)==(float)(l2*l2))
            System.out.println("Isosceles right-angled triangle");//判断等腰直角三角形
        else if (l1 == l2&&l1!=l3 || l1==l3&&l1 !=l2 ||l2==l3&&l2!=l1)
            System.out.println("Isosceles triangle");//判断等腰三角形
        else if (l1*l1+l2*l2==l3*l3 || l1*l1+l3*l3==l2*l2 || l3*l3+l2*l2==l1*l1)
            System.out.println("Right-angled triangle");//判断等腰直角三角形
        else//一般三角形 
            System.out.println("General triangle");
    }
}

 (3)第二次题目集的第九题。

输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
注意:不允许使用Java中和日期相关的类和方法。

要求:Main类中必须含有如下方法,签名如下:

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) ; //求输入日期的下一天
 
 

输入格式:

在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。

输出格式:

    1. 当输入数据非法及输入日期不存在时,输出“Wrong Format”;
    2. 当输入日期合法,输出下一天,格式如下:Next date is:年-月-日

输入样例1:

在这里给出一组输入。例如:

2020 3 10
 

输出样例1:

在这里给出相应的输出。例如:

Next date is:2020-3-11
 

 

    这个题目主要注意以下几点:

    1、是否是闰年对非二月的月份并没有什么影响

    2、即使是二月,如果没有达到28号或者29号,闰年的判断和非闰年的判断也并没有什么区别。

    3、当日期是一年中的最后一天(12月31号)时,和普通的月份增加不一样,月份不是加一,是将月份赋值为1,而且年份要加一。

 

代码清单如下:

import java.util.*;
//本注释由南昌航空大学陆孝彭班22201108郭海涛出品
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int year = input.nextInt();
        int month = input.nextInt();
        int day = input.nextInt();
        if(checkInputValidity(year,month,day)) //如果符合要求就计算下一天
            nextDate(year,month,day);
        else                                    //否则输出Wrong Format
            System.out.println("Wrong Format");
        
    }
    //判断闰年
    public static boolean isLeapYear(int year){ 
        if(year%400 == 0 ||year%4==0&&year%100!=0)
            return true;
        else
            return false;
    }
    
    //判断合法
    public static boolean checkInputValidity(int year,int month,int day){
        if(year<1820 || year>2020 || month<1 ||month>12 || day<1 ||day>31)
            return false;
        else if (day==30&&month==2)
            return false;
        else if (day==31&&(month!=1&&month!=3&&month!=5&&month!=7&&month!=8&&month!=10&&month!=12)){
            return false;
        }
        else if(day>=29&&!isLeapYear(year)&&month==2)
            return false;
        else if(day>29&&isLeapYear(year)&&month==2)
            return false;
        else
            return true;
        
    }
    //判断年月日
    public static void nextDate(int year,int month,int day){
        if(day<30&&month!=2){
            day += 1;
        }

        else if(day<28&&month==2){
            day += 1;
        }

        else if(day==31&&(month==1||month==3||month==5||month==7||month==8||month==10||month==12)){
            if(month!=12)
                month = month+1;
            else{
                month=1;
                year+=1;
            }
            day = 1;
        }
        else if(day == 30&&(month==4||month==6||month==9||month==11)){
            month = month+1;
            day = 1;
        }
        else if(day==30&&(month==1||month==3||month==5||month==7||month==8||month==10||month==12)){
            day=31;
        }
        else if(day ==29&&isLeapYear(year)&&month==2){
            month = month + 1;
            day = 1;
        }
        else if(day==28&&isLeapYear(year)&&month==2){
            day += 1;
        }
        else if(day==28&&!isLeapYear(year)&&month==2){
            month = month + 1;
            day = 1;
        }
        System.out.println("Next date is:"+year+"-"+month+"-"+day);
    }
}

 

 

  (4)第三次题目集的第三题:

定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。

要求:Date类结构如下图所示:

类图.jpg

输入格式:

在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。

输出格式:

    • 当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
    • 当输入日期合法,输出下一天,格式如下:Next day is:年-月-日

输入样例1:

在这里给出一组输入。例如:

1912 12 25
 

输出样例1:

在这里给出相应的输出。例如:

Next day is:1912-12-26
 
 
 
这个题目所需要注意的和上一题一样,只是上一题因为还没有学习设计类的知识,所以只能把所有代码都放到一个主方法中去,而这题则是让我们设计一个时间类,用类中的方法就可以解决求下一天的问题。
 

代码清单如下:

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        Date date =  new Date(input.nextInt(),input.nextInt(),input.nextInt());
        if(date.checkInputValidity())
            date.getNextDate();
        else
            System.out.println("Date Format is Wrong");
    }
}

class Date{
    private int year = 1900;
    private int month = 1;
    private int day = 1;
    int [] mon_maxnum = new int [] {0,31,28,31,30,31,30,31,31,30,31,30,31};
    Date(){}
    Date(int year,int month,int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    
    
    public boolean isLeapYear(int year){//判断闰年
        if(year % 400 ==0 || year % 4 ==0 && year %100 != 0)
            return true;
        else
            return false;
    }
    
    public boolean checkInputValidity(){
        if(year<1900 || year >2000 || month <=0 ||day <=0 ||month>12||day>31)
            return false;
        else if (this.day>mon_maxnum[this.month]&&!isLeapYear(year))
            return false;
        else if (this.month==2 && isLeapYear(year) &&this.day>mon_maxnum[2]+1)
            return false;
        else
            return true;
    }
    
    public void getNextDate(){
        if(this.day<mon_maxnum[this.month])//如果bu是最后一天
            this.day += 1;
        else if(this.month ==2 && isLeapYear(this.year) && this.day==29){//闰年2月29日
            this.day = 1;//3月1日
            this.month = 3;
        }
        else if(this.month ==2 && isLeapYear(this.year) && this.day<=28){
            this.day +=1 ;//天数加1
        }
        else if(this.month ==2 &&!isLeapYear(this.year) && this.day==28){
            this.day = 1;//3月1日
            this.month = 3;
        }
        else if(this.day == mon_maxnum[month]){//当月最后一天
            if (month ==12){
                year += 1;
                month = 1;
                day = 1;
            }
            else{
                month += 1;
                day = 1;
            }
        }
        
        
        System.out.printf("Next day is:%d-%d-%d",this.year,this.month,this.day);
    }
}

 

 (5)第三次作业的第四题:

参考题目3和日期相关的程序,设计一个类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. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

程序主方法如下:

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();

        if (choice == 1) { // test getNextNDays method
            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);

            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) { // test getPreviousNDays method
            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) {    //test getDaysofDates method
            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);
        }        
    }
}
 
 

输入格式:

有三种输入方式(以输入的第一个数字划分[1,3]):

    • 1 year month day n //测试输入日期的下n天
    • 2 year month day n //测试输入日期的前n天
    • 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数

输出格式:

    • 当输入有误时,输出格式如下:
      Wrong Format
    • 当第一个数字为1且输入均有效,输出格式如下:
      year1-month1-day1 next n days is:year2-month2-day2
       
    • 当第一个数字为2且输入均有效,输出格式如下:
      year1-month1-day1 previous n days is:year2-month2-day2
       
    • 当第一个数字为3且输入均有效,输出格式如下:
      The days between year1-month1-day1 and year2-month2-day2 are:值
       

输入样例1:

在这里给出一组输入。例如:

3 2014 2 14 2020 6 14
 

输出样例1:

在这里给出相应的输出。例如:

The days between 2014-2-14 and 2020-6-14 are:2312
 

输入样例2:

在这里给出一组输入。例如:

2 1834 2 17 7821
 

输出样例2:

在这里给出相应的输出。例如:

1834-2-17 previous 7821 days is:1812-9-19
 

输入样例3:

在这里给出一组输入。例如:

1 1999 3 28 6543
 

输出样例3:

在这里给出相应的输出。例如:

1999-3-28 next 6543 days is:2017-2-24
 

输入样例4:

在这里给出一组输入。例如:

0 2000 5 12 30
 

输出样例4:

在这里给出相应的输出。例如:

Wrong Format
 
 
这道题的思路分别如下:
1、求下N天和求下一天方法相同,就是在最开始加入一个循环结构,下一天就循环一次,下N天就循环N次;求上N天也是如此。 
2、在求两日期之间相差的天数时,分别依照年、月、日的方法来求,年是闰年就加366天,是平年就加365天;起始日期月要加上日期所在的月份后每一个月份的最大天数,日用当月最大天数减去起始日期的日,末尾日期月要加上日期所在的月份前每一个月份的最大天数, 日直接加末尾日期的日。
 
这题难度较大,要注意很多细节问题,要注意的问题如下:
1、判断日期非法时要注意日期的界限,年、月、日都不能为负数;平年的二月不能超过28天,闰年的二月不能超过29天;
2、求下N天和求上N天是都要注意,因为输入天数没有限制,所以可能会包含多个闰年,需要对每一年都进行闰年的判断,防止出现多或少闰年2月29号从而造成答案错误的情况。
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();

        if (choice == 1) { // test getNextNDays method
            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);

            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) { // test getPreviousNDays method
            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) {    //test getDaysofDates method
            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 int year = 0;
    private int month = 0;
    private int day = 0;
    int mon_maxnum [] = new int [] { 0,31,28,31,30,31,30,31,31,30,31,30,31};
    
    public DateUtil(){}
    
    public DateUtil(int year,int month,int day){
        this.year = year;
        this.month = month;
        this.day =  day;
    }
    
    public int getYear(){
        return this.year;
    }
    public void setYear(int year){
        this.year = year;
    }
    
    public int getMonth(){
        return this.month;
    }
    public void setMonth(int month){
        this.month = month;
    }
    
    public int getDay(){
        return this.day;
    }
    public void setDay(int day){
        this.day = day;
    }
    
    public boolean checkInputValidity(){
        if(this.year<1820 ||this.year>2020 ||this.month <1||this.month>12||this.day<1||this.day>31)
            return false;
        else if(this.day>30 &&this.day>mon_maxnum[this.month])
            return false;
        else if(this.day>28&&!isLeapYear(this.year)&&this.month==2)
            return false;
        else if(this.day>29&&isLeapYear(this.year)&&this.month==2)
            return false;
        else 
            return true;
    }
    public boolean isLeapYear(int year){
        if(year%400==0||year%4==0&&year%100!=0)
            return true;
        else 
            return false;
    }
    
    public DateUtil getNextNDays(int n){
        for (int i =0;i<n;i++){
            if(this.day<mon_maxnum[this.month])//如果bu是最后一天
            this.day += 1;
        else if(this.month ==2 && isLeapYear(this.year) && this.day==29){//闰年2月29日
            this.day = 1;//3月1日
            this.month = 3;
        }
        else if(this.month ==2 && isLeapYear(this.year) && this.day<=28){
            this.day +=1 ;//天数加1
        }
        else if(this.month ==2 &&!isLeapYear(this.year) && this.day==28){
            this.day = 1;//3月1日
            this.month = 3;
        }
        else if(this.day == mon_maxnum[month]){//当月最后一天
            if (month ==12){
                year += 1;
                month = 1;
                day = 1;
            }
            else{
                month += 1;
                day = 1;
            }
        }
        }
        return  this;
    }
    
    public DateUtil getPreviousNDays(int n){
        for(int i = 0 ;i< n ;i++){
            if(this.day==1&&this.month==1){
                year -=1;
                month = 12;
                day = 31;
            }
            else if(this.day!=1)
                this.day -= 1;
            else if(this.month==3 && this.day ==1 && isLeapYear(this.year)){
                day = 29;
                month -= 1;
            }
            else if(this.month==3 && this.day ==1 && !isLeapYear(this.year)){
                day = 28;
                month -=1;
            }
            else if(this.day==1 && (this.month== 5||this.month ==7||this.month==10||this.month==12)){
                day = 30;
                month -=1;
            }
            else {
                day = 31;
                month -=1;
            }
        }
        return this;
    }
    
    public boolean compareDates(DateUtil date){//当前日期在输入日期后为真
        if(this.year>date.year)
            return true;
        else if(this.year == date.year && this.month > date.month)
            return true;
        else if(this.year == date.year && this.month==date.month && this.day > date.day)
            return true;
        else
            return false;
    }
    
    public boolean equalTwoDates(DateUtil date){
        if(this.year == date.year && this.month == date.month && this.day == date.day)
            return true;//日期相同
        else 
            return false;
    }
    
    public int getDaysofDates(DateUtil date){
        int count = 0;
        
        if(equalTwoDates(date))//如果日期相同
            return 0;
        else if(!compareDates(date)){//当前日期在输入日期前
            for(int i = this.year +1;i < date.year ;i++){//除去起止年
                if(isLeapYear(i))
                    count +=366;
                else
                    count +=365;
            }
            
            for(int j = this.month + 1;j<=12;j++){//加上初始年多余天数
                if(!isLeapYear(this.year) && month==2 || j!=2)
                    count+=mon_maxnum[j];
                else if (isLeapYear(this.year)&&j==2)
                    count+=29;
            }
            if(!isLeapYear(this.year) && this.month==2 || this.month!=2 )
                count += mon_maxnum[this.month]-this.day;
            else if(isLeapYear(this.year) && this.month==2)
                count += 29 - this.day;
            
            for(int j = 1;j<date.month;j++){//加上末尾年多于天数
                if(!isLeapYear(date.year) && j==2 || j!=2)
                    count+=mon_maxnum[j];
                else if (isLeapYear(date.year)&&j==2)
                    count+=29;
            }
            count += date.day;//加上终止年的终止月的终止日前的天数
        }
        else if(compareDates(date)){//当前日期在输入日期前
            for(int i = date.year +1;i < this.year ;i++){//除去起止年
                if(isLeapYear(i))
                    count +=366;
                else
                    count +=365;
            }
            
            for(int j = date.month + 1;j<=12;j++){//加上初始年多余天数
                if(!isLeapYear(date.year) && month==2 || j!=2)
                    count+=mon_maxnum[j];
                else if (isLeapYear(date.year)&&j==2)
                    count+=29;
            }
            if(!isLeapYear(date.year) && date.month==2 || date.month!=2 )
                count += mon_maxnum[date.month]-date.day;
            else if(isLeapYear(date.year) && date.month==2)
                count += 29 - date.day;
            
            for(int j = 1;j<this.month;j++){//加上末尾年多于天数
                if(!isLeapYear(this.year) && j==2 || j!=2)
                    count+=mon_maxnum[j];
                else if (isLeapYear(this.year)&&j==2)
                    count+=29;
            }
            count += this.day;//加上终止年的终止月的终止日前的天数
        }
        
        
        return count;
    }
    
    public String showDate(){
        String date0 = Integer.toString(this.year);
        String date1 = Integer.toString(this.month);
        String date2 = Integer.toString(this.day);
        String date = new String();
        date = date0 + "-" + date1 +"-" +date2;
        return date;
    }
    //本注释由22201108-郭海涛同学荣誉出品
}

 

三、踩坑心得

在这三次题目中,在解决很多题目的时候都相应的遇到了一些困难和问题,在这总结一下犯过的错误,踩过的坑,以免在下次还犯同样的错误。

第一次题目集的第七题:输入的是一个无序数列,这样在进行判断就比较麻烦,因为重复数据有可能一个在最开始,一个在最后,我一开始使用的是嵌套循环来判断,但是这样书写出来的程序运行效率非常低,在提交结果的时候出现了运行超时。于是这是后就想到了排序,因为如果有重复的数据,那这多个数据在排序后的位置一定是紧密挨着的,而且java中提供了数组排序的方法,排序十分方便,只要出现重复的数据,直接跳出循环,这样在一定程度上就能减少程序的运行时间,从而避免了出现运行超时的错误。

实现后的代码如下

import java.util.*;

public class Main{
    public static void main(String[] args){
        boolean flag = false;
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        int [] num = new int [n];
        for(int i = 0; i<n;i++){
             num[i] = input.nextInt();
        }
        Arrays.sort(num);
        for(int i = 0;i<n-1;i++){
            if(num[i] == num[i+1]){
                flag = true;
                break;
            }
        }

        if(flag)
            System.out.print("YES");
        else
            System.out.print("NO");
    }
}

第二次题目集的第五题:因为输入的学号是连续的,中间没有空格,而又要对中间的几个特定位数的数字进行判断,一开始我想到的是创建一个整形数组来对特定位数来判断,但是输入的时候数字之间没有空格,不知道如何分割数字,后来想到了在上学期C语言课上曾讲过的要减少位数可以直接做%运算,例如111只想要后两位数字可以直接111%100,这样就能留下11这个数字。所以我用%运算来对学号的不同位数进行特定的判断,从而完成题目。

实现后的代码如下

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int num = input.nextInt();
        if(num/10000000<1 || num/10000000>=10)
            System.out.print("Wrong Format");
        else if((num/10000)%100!=01&&(num/10000)%100!=02&&(num/10000)%100!=03&&(num/10000)%100!=20)
            System.out.print("Wrong Format");
        else{
            System.out.println("入学年份:20"+ num/1000000+"年");
            if((num/10000)%100==01)
                System.out.println("学院:材料学院");
            if((num/10000)%100==02)
                System.out.println("学院:机械学院");
            if((num/10000)%100==03)
                System.out.println("学院:外语学院");
            if((num/10000)%100==20)
                System.out.println("学院:软件学院");
            System.out.printf("班级:%02d\n",(num/100)%100);
            System.out.printf("学号:%02d",num%100);
        }
        
    }
}

第二次题目集的第六题:在这个题目中,需要判断字符串中是否含有字符串-1,而这个判断一开始我并不知道用什么方法实现,一开始我用字符判断,先判断"-",在判断"1",但是"-1"这个字符串是紧密挨着的,这样判断就会不管-和1是不是紧密挨着,都会认为含有-1这个字符串,后来我去菜鸟教程找字符串相关的资料,发现字符串有一个contains方法,可以判断字符串中是否含有某字符(串),使用这个方法就可以非常快速便利的判断字符串中是否含有"-1"这个字符串,从而可以直接判断字符串输入是否非法。

实现后的代码如下

import java.util.*;

public class Main{
    public static void main(String[] ars){
        Scanner input = new Scanner(System.in);
        String str = new String();
        str = input.nextLine();
        if(!str.contains("-1")){
            System.out.print("Wrong Format");
        }
        else{
            int i =0;
            while(true){
                if(str.charAt(i) == '-' && str.charAt(i+1) == '1')
                    break;
                if(str.charAt(i) == '1' || str.charAt(i) == '0')
                    System.out.print(str.charAt(i));
                i++;  
                }
        }
    }
}

 

四、改进建议

  因为这三个题目集是在不同的时间写的,每写完一个题目集同时也学习了一些新的知识,所以现在回头看自己以前写的代码,有很多的地方可以改进。

第二个题目集的第九题,那个月份我是依据每个月的最大日期只有31、28(29)、30这几种情况来分类的

public static void nextDate(int year,int month,int day){
        if(day<30&&month!=2){
            day += 1;
        }

        else if(day<28&&month==2){
            day += 1;
        }

        else if(day==31&&(month==1||month==3||month==5||month==7||month==8||month==10||month==12)){
            if(month!=12)
                month = month+1;
            else{
                month=1;
                year+=1;
            }
            day = 1;
        }
        else if(day == 30&&(month==4||month==6||month==9||month==11)){
            month = month+1;
            day = 1;
        }
        else if(day==30&&(month==1||month==3||month==5||month==7||month==8||month==10||month==12)){
            day=31;
        }
        else if(day ==29&&isLeapYear(year)&&month==2){
            month = month + 1;
            day = 1;
        }
        else if(day==28&&isLeapYear(year)&&month==2){
            day += 1;
        }
        else if(day==28&&!isLeapYear(year)&&month==2){
            month = month + 1;
            day = 1;
        }
        System.out.println("Next date is:"+year+"-"+month+"-"+day);
    }

但是如果直接用一个数组来存储每个月的最大天数,可以简化我们的代码,便于检查错误。

int [] mon_maxnum = new int [] {0,31,28,31,30,31,30,31,31,30,31,30,31};

public void getNextDate(){
        if(this.day<mon_maxnum[this.month])//如果bu是最后一天
            this.day += 1;
        else if(this.month ==2 && isLeapYear(this.year) && this.day==29){//闰年2月29日
            this.day = 1;//3月1日
            this.month = 3;
        }
        else if(this.month ==2 && isLeapYear(this.year) && this.day<=28){
            this.day +=1 ;//天数加1
        }
        else if(this.month ==2 &&!isLeapYear(this.year) && this.day==28){
            this.day = 1;//3月1日
            this.month = 3;
        }
        else if(this.day == mon_maxnum[month]){//当月最后一天
            if (month ==12){
                year += 1;
                month = 1;
                day = 1;
            }
            else{
                month += 1;
                day = 1;
            }
        }
        
        
        System.out.printf("Next day is:%d-%d-%d",this.year,this.month,this.day);
    }

第三个题目集的第四题,在求两个确定日期之间相差的天数时,思路是求年->月->日,这样思路很清晰,但是很不好实现,在分别思考对初始日期月份和天数和末尾日期月份和天数的处理都比较复杂,显得逻辑很混乱。可以参考求下N天的方法,直接从小的那一天开始,如果日期不等于大的日期,就一直加天数,和求下N天的方法差不多,就是循环结束的条件改变了。

 

五、总结

这三次题目集可以说是真正敲开了Java学习的大门,难度不大,题量也适中,考察的大都也是关于一些常用的类及其常用的方法,而我们学习Java,不仅仅是语法上的学习,更是对这种面向对象编程思想的学习,作为编程菜鸟的我基础还很薄弱,而加强基础的最好方法就是多写练习,在练习中锻炼自己的语法,设计类和方法的结构。

在这三次题目集中学习到了字符串的很多操作方法,还有Java的计算精度如何解决,长数字如何得到特定位数的短数字等等,还有关于类和方法的设计,这些都是我们作为一名软件工程的学生应该要熟练掌握的知识,同时也出现了许多问题,就如写过的求下一天在下一个题目集出现仍旧不能一次写好,这就证明我并没有完全理解求下一天这个题目该如何去分析,如何去编写相应的程序。对书写的程序也有很多可以改进的措施,如:添加注释,让代码更容易被理解;改进程序算法,让所写程序逻辑更通畅;学习一些常用类的常用方法,让我们的程序更简便、高效。这些都是我可以再进一步地理解、学习、钻研的。

这三次题目集难度都不大,但是由于其他课程也有许多繁琐的事情,加上还有项目、调研需要完成,导致写PTA的时间并不是很充裕,所以有一次题目集我开始的很早,但还是只在结束前一天才完成,效率比较低,所以下一次就要提高效率了,尽量把PTA早点完成

 

posted @   Swery_X  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示