题目集1~3总结心得

1.前言

PTA第一次题目集难度不是很大,第一次接触java,多看看书可以做出来。第二次题目集的难度也很低,只有少量细节要注意,最后一题还用到了java中的方法调用。前两次题目是java的入门练习,没有涉及面向对象。第三次题目集相对于前两次难度有较大的提升,初次接触到了类,需要学会定义类、创建类、使用类,我认为这方面还有待加强。

2.设计与分析

训练集001第七题:7-7有重复的数据

在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。

你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES”这三个字母;如果没有,则输出“NO”。

输入格式:

你的程序首先会读到一个正整数n,n[1,100000],然后是n个整数。

输出格式:

如果这些整数中存在重复的,就输出:

YES

否则,就输出:

NO

输入样例:

5
1 2 3 1 4

输出样例:

YES

试题分析:

要求先输一个数n作为输入数字的个数,然后输入n个数,如果有重复则输出no没有就yes。

源代码展示:

查看代码
 import java.util.Scanner;
public class Main{
    public static void main (String[] args){
         Scanner input =new Scanner(System.in);
        int n = input.nextInt();
        int i,k=0,j;
        int[] a=new int[n];
        for(i=0;i<n;i++)
        {a[i] = input.nextInt();
         for(j=0;j<i;j++)
            if(a[i]==a[j])
                k++;
         if(k==1)
         {System.out.print("YES");
                break;}
                k=0;}
                

if(k==0) 
    System.out.print("NO");
    }}

 SourceMonitor生成的报表内容:

代码分析总结:

本题难度不是很高,用到数组存入n个数,使用循环来判断是否相同,如果相同直接结束循环。

采坑心得:

在提交过程中由于使用的循环和数组太过于复杂导致代码支行超时

改进建议:

可以将n个数存入一个字符串,然后比较字符串中是否有重复字符。可以一边输入数据,一边和前面的数据比较,能提高效率。

 

训练集001第十二题:7-12 列出最简真分数序列*

 
 
 

按递增顺序依次列出所有分母为N(10 <= N <= 40),分子小于N的最简分数。

输入格式:

分母 N。

输出格式:

分数之间用逗号分开(含最末逗号)

输入样例:

10
 

输出样例:

1/10,3/10,7/10,9/10,

试题分析:

输入一个数做为n,输出所有以n为分母的最简分数,本题要找出所有不能n整除且最大公因数为1的数,按从小到大输出。

源代码展示:

查看代码
 import java.util.Scanner;
public class Main{
    public static void main(String[] args){
Scanner input=new Scanner (System.in);
        
        int n=input.nextInt();


int i,j=2,flat=0;

  for(i=1;i<n;i++){
for(j=2;j<n;j++)
{
   if(i%j==0&&n%j==0)
   flat=1;
}
  if(flat==0)
{
   System.out.print(i+"/"+n+",");
}flat=0;
}
    }}

 SourceMonitor生成的报表内容:

代码分析总结:

 用了两个for循环来测试,如果有一个小于n的数i,一个小于n大于1的数j,只有当i和n都能被j整除时,说明i/n可以约分,则不输出i/n,否则能输出 i/n,输出或不输出用flag来区分,当需要输出flag等于0此时输出否则flag等于1,不输出 。

采坑心得:

 一开始只考虑输出i/n使n%i!=0就输出结果导致一些能约分的分数也被输出

由于一开始没有考虑到可约分的情况,后将代码改进,所以做题时要仔细思考题目,想好所有可能 。

改进建议:

 使用flag的方式来控制输出是可以使用的,但不是最优解,可以改进使代码更简单易懂。

 

 

训练集002第八题:7-8 判断三角形类型

输入三角形三条边,判断该三角形为什么类型的三角形。

输入格式:

在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。

输出格式:

(1)如果输入数据非法,则输出“Wrong Format”;
(2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”;
(3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”;
(3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”;
(5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”;
(6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”;
(7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。

输入样例1:

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

50 50 50.0
 

输出样例1:

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

Equilateral triangle
 

输入样例2:

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

60.2 60.2 80.56
 

输出样例2:

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

Isosceles triangle
 

输入样例3:

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

0.5 20.5 80
 

输出样例3:

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

Wrong Format

 

试题分析:

本题要求判断三角形的类形,分为多种情况,非常考验个人的逻辑能力,应该首先判断是否是三角形,然后判断类型,要求会用多个判断语句判断情况。

源代码展示:

查看代码
 import java.util.Scanner;
public class Main{
    public static void main (String[] args){
        Scanner input=new Scanner(System.in);
        double t;

            
        double[] a=new double[3];
        for(int i=0;i<3;i++){
             a[i]=input.nextDouble();
        }
        for(int i=0;i<3;i++)
            if(a[i]>200||a[i]<1){
                System.out.print("Wrong Format");
                System.exit(0);
            }
        for(int j=0;j<2;j++)
        for(int i=0;i<2-j;i++){
            if(a[i]>a[i+1]){
                t=a[i];
                a[i]=a[i+1];
                a[i+1]=t;
            }}
            if(a[0] + a[1] <= a[2]){
                System.out.print("Not a triangle");
                System.exit(0);
            }
                if(a[0]==a[2]&&a[0]==a[1]){
                    System.out.print("Equilateral triangle");
                System.exit(0);
                }
                if((a[0]==a[1]&&a[0]!=a[2])||(a[1]==a[2]&&a[0]!=a[1])){
                    if(Math.abs(a[2]*a[2]-a[0]*a[0]-a[1]*a[1])<=0.1)
                        System.out.print("Isosceles right-angled triangle");
                    else
                    System.out.print("Isosceles triangle");
                System.exit(0);
                }
            if(a[0]!=a[1]&&a[1]!=a[2]){
                   if((a[2]*a[2]-a[0]*a[0]-a[1]*a[1])==0)
                       System.out.print("Right-angled triangle");
                else
                    System.out.print("General triangle");
            }
        }}

 SourceMonitor生成的报表内容:

代码分析总结:

首先判断输入值是否合法,然后用for循环将三边长按从小到大排列,用两小边是否大于一大边的方法判断是否能构成三角形,之后比较两小边与最大边的关系,按要求输出对应三角形。

采坑心得:

因为输入的数据为double类型会发生计算精度丢失,当我算计是否是直角三角形的时候两边的平方和等于第三边的平方,计算值可能会有很小的误差,导致正确无法判断是否是直角三角形,导致有一个测试点一直过不了

改进建议:

在网上查阅资料得知由于double计算精度丢失导致错误,后使用网上的方法使用BigDecimal。将double转为BigDecimal的时候,需要先把double转换为字符串,然后再作为BigDecimal(String val)构造函数的参数,这样才能避免出现精度问题。

 

 

训练集002第三题:7-3 房产税费计算2022

房屋交易在日常生活中非常常见的事情,房屋交易时要额外支付各种税费,按2022年房产交易新政策的规定买房人应缴纳税费包括:

1、契税:首次购房评估额90平(含)内1%、90平-144平(含)内1.5%,超过144平或非首 次3%,买方缴纳。

2、印花税:房款的0.05%。

3、交易费:3元/平方米。

4、测绘费:1.36元/平方米。

5、权属登记费及取证费:一般情况是在200元内。

输入格式:

四个数据,以空格分隔:
1、第几次购房(整数)
2、房款(整数/单位万元)
3、评估价(整数/单位万元)
4、房屋面积(浮点数/单位平方米)。
例如:1 100 100 90。

输出格式:

契税、印花税、交易费、测绘费(以元为单位),以空格分隔。例如:10000.0 500.0 270.0 122.4

输入样例:

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

1 100 100 90
 

输出样例:

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

10000.0 500.0 270.0 122.4

试题分析:

本题比较简单主要考查对不同类型之间的转换还有类型之间的计算。只要仔细读题可以做出来 。

源代码展示:

查看代码
 import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        int a = input.nextInt();
        int b=input.nextInt();
        int c=input.nextInt();
        b=b*10000;
        c=c*10000;
        double d=input.nextDouble();
        double q=0;
        if(a==1){
            if(d<=90)
                 q=c*0.01;
            if(d>90&&d<=144)
                 q=c*0.015;
            if(d>144)
                 q=c*0.03;
        }
        if(a>1)
             q=c*0.03;
        double y=b*0.0005;
        double j=3*d;
        double ce=1.36*d;
        System.out.print((float)q+" "+(float)y+" "+(float)j+" "+(float)ce);
    }
}

 SourceMonitor生成的报表内容:

代码分析总结:

用if来判断房子的大小,计算契税等各种费用,最后输出结果。

采坑心得:

第一次提交没有用float类型,导致测试点过不了,但逻辑是对的,费了很多时间查找原因。

改进建议:

将结果强制转换成float类型。

 

 

训练集002第九题:7-9 求下一天

输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[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
 

输入样例2:

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

2025 2 10
 

输出样例2:

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

Wrong Format

试题分析:

本题要求输入一个日期,然后输出这个日期的下一天,是目前为止最复杂的一题,这题需要判断闰年,判断月份的大小,判断日期的下一天是否需要加月份或加年份。题目还规定要自己构造方法来判断条件,不可以用java原有的判断日期方法。

源代码展示:

查看代码
 import java.util.Scanner;
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();
        nextDate(year,month,day);
    }

public static boolean isLeapYear(int year) //判断year是否为闰年,返回boolean类型 
{
    boolean isLeapYear;
  if((year%4==0&&year%100!=0 )||year%400==0)
         isLeapYear=true;
    else
   isLeapYear=false;
    return isLeapYear;
}
public static boolean checkInputValidity(int year,int month,int day)//判断输入日期是否合法,返回布尔值
{
    boolean checkInputValidity=true;
    if(year>2020||year<1820||month<1||month>12||day>31||day<1)
    {checkInputValidity=false;
    }
    if(isLeapYear(year)){
        if(month==2&&day>29)
            checkInputValidity=false;
    }
    else if(month==2&&day>28)
            checkInputValidity=false;
    if(month==4||month==6||month==9||month==11){
        if(day>30)
            checkInputValidity=false;
        
    }return checkInputValidity;
}
public static void nextDate(int year,int month,int day)  //求输入日期的下一天
{
    if(checkInputValidity(year,month,day)){
        if(month==12&&day==31){
            System.out.print("Next date is:"+(year+1)+"-1-1");
            System.exit(0);
        }
        if(isLeapYear(year)){
            if(month==2&&day==29){
                System.out.print("Next date is:"+year+"-3-1");
                System.exit(0);
            }
        }
        else if(month==2&&day==28){
            System.out.print("Next date is:"+year+"-3-1");
            System.exit(0);
        }
        if(month==4||month==6||month==9||month==11){
            if(day==30){
                System.out.print("Next date is:"+year+"-"+(month+1)+"-1");
                System.exit(0);
            }
        }
        else if(day==31){
            System.out.print("Next date is:"+year+"-"+(month+1)+"-1");
            System.exit(0);
        }
        
    }
    else{
        System.out.print("Wrong Format");
        System.exit(0);
    }
    System.out.print("Next date is:"+year+"-"+month+"-"+(day+1));
}
}

 SourceMonitor生成的报表内容:

代码分析总结:

主要的功能由各种方法实现先定义一个判断是否为闰年的类如果是返回真,不是返回假,定义一个判断日期是否合法的方法,如果输入日期不合法返回假,合法返回真。定义一个计算下一天的方法,需要在此方法里用到前面两种方法,由于每个月天数不一样,所以要复杂的判断。

采坑心得:

一开始没有考虑二月份的情况导致二月可能会加到30天

改进建议:

在最后算加一天的时候,我列出了所有的情况,将每一种情况的代码都写出来,使代码非常复杂,思路不够清晰。可以将不同月份的天数存入一个数组,可以简化代码,更好懂。

训练集003第三题:7-3 定义日期类

定义一个类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
 

输入样例2:

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

2001 2 30
 

输出样例2:

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

Date Format is Wrong

试题分析:

编写一个日期类Date,三个私有属性年月日,写出带参数构造方法、无参构造方法、属性的getter、setter方法以及判断闰年、判断日期是否合理、输出下一天等方法。

源代码展示:

查看代码
 import java.util.Scanner;
class Date{
    private int year;
    private int month;
    private int day;
    public Date(int year,int month,int day){
        this.year=year;
        this.month=month;
        this.day=day;
    }
    public Date(){
        
    }
    public int getYear(){
        return year;
    }
    public int getMonth(){
        return month;
    }
    public int getDay(){
        return day;
    }
    public void setYear(int year){
        this.year=year;
    }
    public void setMonth(int month){
        this.month=month;
    }
    public void setDay(int day){
        this.day=day;
    }
    public boolean isLeapYear(int year){
            boolean isLeapYear;
  if((year%4==0&&year%100!=0 )||year%400==0)
         isLeapYear=true;
    else
   isLeapYear=false;
    return isLeapYear;
    }
    public boolean checkInputValidity(){
        if(month>12||month<0||year<1900||year>2000)
            return false;
        else{
      //  if(isLeapYear(int year))
       //     int[] a={0,31,29,31,30,31,30,31,31,30,31,30,31};
         //   else
        int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            a[2]=29;
        if(day>a[month]||day<=a[0])
            return false;
        else 
            return true;}
    }
    public void getNextDate(){
        int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            a[2]=29;
        
        if(day==a[month])
        {this.month=month+1;
         this.day=1;}
        else
            this.day=day+1;
        if(month==13){
            this.month=1;
            this.year=year+1;
        }
        
    }
}
public class Main{
public static void main(String[] args) {
    Scanner sc=new Scanner(System.in);
    int year=sc.nextInt();
    int month=sc.nextInt();
    int day=sc.nextInt();
    Date a1=new Date();
    a1.setYear(year);
    a1.setMonth(month);
    a1.setDay(day);
    if(a1.checkInputValidity()){
        a1.getNextDate();
        System.out.print("Next day is:"+a1.getYear()+"-"+a1.getMonth()+"-"+a1.getDay());
        
    }
    else 
        System.out.print("Date Format is Wrong");
}}

 SourceMonitor生成的报表内容:

代码分析总结:

这里我定义了一个日期类,里面有判断闰年、判断日期是否合理、输出下一天的方法。每种属性都有对应的getter和setter方法。在计算每个月的天数时我用了一个数组int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31},如果是闰年的话a[2]=29,如果遇到天数,月份大于规定值,就向前进一,最后输出结果。

采坑心得:

一开始判断闰年后我将数组改为int[] a={0,31,29,31,30,31,30,31,31,30,31,30,31},通过这种方式来改变二月份的天数,但由于我上面已经定义过此数组,不能重复定义导致报错。

如果以这种方式就会报错。

改进建议:

代码使用的变量名不规范,在判断闰年的方法里返回真值和假值还可以写的更简略一些。代码格式不够标准。

 

 

训练集003第四题:7-4 日期类设计

全屏浏览题目
切换布局
作者 段喜龙
单位 南昌航空大学

参考题目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中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

 

输入格式:

有三种输入方式(以输入的第一个数字划分[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

试题分析:

本题是上一题的加强版,这题增加了计算前n天后n天的功能,还要求可以算出两个日期的差值。本题已经给出了固定的主方法,这样迫使我们必须严格按照主方法思路和要求写,编写的代码必须与主方法相适用,本题还要在定义类的方法里创建一个类本身,以前不知道可以这样做

源代码展示:


查看代码
 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 day;
    private int month;
    private int year;
    
    public DateUtil(int year,int month,int day) {
    	this.day = day;
    	this.month = month;
    	this.year = year;
    }
    
    public int getYear() {
    	return year;
    }
    
    public int getDay() {
    	return day;
    }
    
    public int getMonth() {
    	return month;
    }
    
    public boolean checkInputValidity() {
    	boolean a;
    	int[] n = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
        {
        	n[2] = 29;
        }
        if(year>=1820&&year<=2020&&month>0&&month<=12&&day<=n[month]&&day>0) {
        	a = true;
        }
        else {
        	a = false;
        }
    	return a;
    }
    
    public  boolean isLeapYear(int year) 
	{
		
		if((year%4 == 0&&year%100 != 0)||(year%400 == 0))
			return true;
			else return false;
	}
    public DateUtil getPreviousNDays(int m){
        int day1 = day;
    	int month1 = month;
    	int year1 = year;
        
        int i;
        
        
        int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
                     while(true){
           if(isLeapYear(year1)){
               if(m>366){
                   m=m-366;
                   year1--;
               }
               else
                   break;
           }
           else{
               if(m>365){
                   m=m-365;
                   year1--;
               }
               else
                   break;
           }
       }
        for(i=0;i<m;i++){
        if(isLeapYear(year1))
            a[2]=29;
        
        if(day1==1)
        {month1=month1-1;
        if(month1==0){
            month1=12;
            year1=year1-1;
        }
         day1=a[month1];}
        else
            day1=day1-1;
        }
        
       
            DateUtil beforedate = new DateUtil(year1, month1, day1);
    	return beforedate;
    }
     public DateUtil getNextNDays(int m){
                 int day1 = day;
    	int month1 = month;
    	int year1 = year;
       while(true){
           if(isLeapYear(year1)){
               if(m>366){
                   m=m-366;
                   year1++;
               }
               else
                   break;
           }
           else{
               if(m>365){
                   m=m-365;
                   year1++;
               }
               else
                   break;
           }
       }
         
         while(true){
             int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year1))
            a[2]=29;
             if(m+day1<=a[month1])
             {day1=day1+m;
              break;}
             if(m+day1>a[month1]){
                 m=m-a[month1];
                 month1++;
             }
             if(month1==13){
                 month1=1;
                 year1++;
             }
             
         }
        
        
                
                
        
         DateUtil nextdate = new DateUtil(year1, month1, day1);
    	return nextdate;
     }
    public String showDate() {
   
    	return (year+"-"+month+"-"+day);
    }

    public int getDaysofDates(DateUtil toDate) {
    	boolean b = equalTwoDates(toDate);
        boolean x = compareDates(toDate);
int[] a={0,31,28,31,30,31,30,31,31,30,31,30,31};
        //   	int[] m = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
    	int k = 0;
    	int i;
    	if(b) {
    		k = 0;
    	}
        else{
            if(x){
                if(year<=toDate.year){
                    for(i=year;i<toDate.year;i++){
                        if(isLeapYear(i))
                            k=k+366;
                        else
                            k=k+365;
                    }
                }
         //       if(year==toDate.year){
                    if(month<toDate.month){
                        for(i=month;i<toDate.month;i++){
                            
        if(isLeapYear(toDate.year))
            a[2]=29;
                            k=k+a[i];
                        }
                    }
                    if(month>=toDate.month){
                        for(i=toDate.month;i<month;i++){
                     if(isLeapYear(toDate.year))
                    a[2]=29;
                            k=k-a[i];
                        }
                    }
                
                 k=k+toDate.day-day;
            }
            else{
                //
                                if(year>=toDate.year){
                    for(i=toDate.year;i<year;i++){
                        if(isLeapYear(i))
                            k=k+366;
                        else
                            k=k+365;
                    }
                }
         //       if(year==toDate.year){
                    if(toDate.month<month){
                        for(i=toDate.month;i<month;i++){
                            
        if(isLeapYear(year))
            a[2]=29;
                            k=k+a[i];
                        }
                    }
                    if(toDate.month>=month){
                        for(i=month;i<toDate.month;i++){
                     if(isLeapYear(year))
                    a[2]=29;
                            k=k-a[i];
                        }
                    }
                
                 k=k-toDate.day+day;
            }
        }
        return k;}
        
        
        
  

    
    public boolean equalTwoDates(DateUtil date) {
          if(date.year==year&&date.day==day&&date.month==month) {
          return true;
    }
          else {
          return false;
    }
    }
    
    public boolean compareDates(DateUtil date) {
    if(year>date.year) {
              return false;
    }
             else if(year<date.year){
             return true;
            }
        else {
              if(month>date.month) {
              return false;
              }
              else if(month<date.month) {
              return true;
         }
              else {
              if(day>date.day) {
              return false;
               }
              else {
                  return true;
                  }
             }
         }
    }


    
    
}

 SourceMonitor生成的报表内容:

代码分析总结:

判断闰年的方法没有变,重点是由往前一天变到n天,就要考虑有跨年,跨月的情况,我利用上一题的原理,相当于往前加n个一天,用一个for循环每次往前加一天,跨越月份或年份就往前加一,天数从1开始重新记算,用if来实现。往前多少天也是同一原理,先算往前一天,然后用循环。题目还要求可以求两日期的天数差,首先要判断前后输入的日期谁大谁小,按题目要求如果前面的日期大,就返回真,后面大返回假。计算日期差值,以前面的日期大为例:先判断两日期年份是否相同,如果相同就判断月份,不相同就两个年份相减每差一年就加上对就年的天数,然后判断月份,如果是前面的日期月份大,就加上这两月份相差的天数,要是整的月份,反之减去相差天数,最后判断天数,与月份逻辑相同,最后将年月日的得的结果放一起就是差的天数。

采坑心得:

由于测试点可能会加前n天,n的数字太大导致运行超时

前后n天的最大测试值不对,后来我将大于一年的天数直接加了一年,可以避免循环太大使运行超时。

改进建议:

我认为用循环一天一天的算效率非常低下,可以先判断是否可以用年算,然后判断是否可以用月算,最后在判断天数,效率可能会更高。

 

 3、总结

通过三次题目集,我对java的语法有了一定的掌握和理解,通过做题可以发现很多自己的问题,需要不断的改善。我学会了用java进行输入输出,区分了它与c语言中的输入输出不同的地方,我学会了如何在java里定义使用不同数组,java里还有很多对字符串的操作,比c语言更简洁。我还学习了用java定义方法,使用方法。前两次题目集更多是java的基本语法练习,第三次,我接触到了类,学习了解了java的面向对象的设计方法,可以初步使用类来编写一些简单的程序。改进方面:我们直接跳过基本语法,开始学习类,虽然通过做题有了基本了解,但仍有许多细节没有学到,今后要持续学习前面的内容,也是为了未来打下基础。对教学以及作业的建议:老师这种让我们自己自学的方法,可以锻炼我们的自学能力。就是题有点多。

 

posted @ 2023-03-26 18:04  坤坤有手不行  阅读(46)  评论(1)    收藏  举报