java第一次作业报告

发布时间 2023-03-26 23:05:58作者: 王予琦

第一次作业报告

一.前言

第一次做作业报告,可能不太规范和清楚,请多多指教。

1.知识点:

(1)第一次题目集:类型的转换,小数输出,对字符串的提取,转换,分析。
(2)第二次题目集:对非法输入数据的判断,方法的使用,对字符串的提取,转换,分析。
(3)第三次题目集:类的编写,私有属性的使用,日期的计算。

2.题量和难度:

第一次作业除了7-10和其他题目不是一个等级外整体思维难度较低,题量较大,开始学习编程都有的最基本的语法。
第二次作业思维难度一般,题量偏大,需要学的内容并不多,要点是7-9的方法的学习,用法和c语言的函数类似。
第三次作业思维难度较大,题量很少,要学的东西很多,要点是java特有的封装和类的进一步使用,对象的用法类似c语言的结构体。
三次作业逐层递进都是些基本内容,涉及多方面的入门知识点,对刚学的我们来说需要上网查诸多东西,帮助我们从c语言转向java。

二.设计与分析

1.题目集3(7-3):定义日期类

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

输入格式:

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

输出格式:

  • 当输入数据非法及输入日期不存在时,输出“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
(1)代码如下

import javax.print.DocFlavor;
import java.util.Scanner;
import java.time.LocalDate;
public class Main {
    public static void main(String[] args) {
        Scanner num=new Scanner(System.in);
        int a = num.nextInt();
        int b = num.nextInt();
        int c = num.nextInt();
        Date date = new Date();
        date.Date(a,b,c);
        date.getNextDate();

    }
}
class Date{
    private int year;
    private int month;
    private int day;
    private int mon_maxnum[] = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
    public void Date(){
        year = 0;
        month = 0;
        day = 0;
    }
    public void Date(int a,int b,int c){
        year = a;
        month = b;
        day = c;
    }

    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){
        if(year%400==0||(year%4==0&&year%100!=0))
            return true;
        else
            return false;
    }
    public  boolean checkInputValidity(){
        if(month>12)
            return true;
        if(isLeapYear(year)){
            mon_maxnum[2]=29;
        }
        if(day>mon_maxnum[month]||month>12||year>2000||year<1900||day<1||month<1){
            return true;
        }
        else
            return false;
    }
    public void getNextDate(){
        if(checkInputValidity()){
            System.out.println("Date Format is Wrong");
            System.exit(0);
        }
        if (day == mon_maxnum[month]&&month!=12) {
            month++;
            day=1;
        }
        else if(day == mon_maxnum[month]&&month==12){
            day=1;
            year++;
            month=1;
        }
        else
            day++;
        System.out.println("Next day is:"+year+"-"+month+"-"+day);
    }
}

(2)解释与心得
首先要考虑数据非法及输入日期不存在的问题,这时只会输出"Date Format is Wrong"不会输出其他语句,所以我在输出后又用了System.exit(0)来结束进程。

if(checkInputValidity()){
            System.out.println("Date Format is Wrong");
            System.exit(0);
        }

其次闰年时2月有29天要比平年多差一天,我把闰年数组的28天改成29天。

public  boolean checkInputValidity(){
        if(month>12)
            return true;
        if(isLeapYear(year)){
            mon_maxnum[2]=29;
        }

最后还要考虑跨年跨月的情况进行分类讨论。

if (day == mon_maxnum[month]&&month!=12) {
            month++;
            day=1;
        }
        else if(day == mon_maxnum[month]&&month==12){
            day=1;
            year++;
            month=1;
        }
        else
            day++

2.题目集3(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中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
程序主方法如下:

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)代码如下:

import javax.print.DocFlavor;
import java.util.Scanner;
import java.time.LocalDate;
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) {
            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) { 
            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 int year;
    private int month;
    private int day;
    private int ping[] = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
    private int run[] = new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};
    public DateUtil(int year,int month,int day){
        this.year=year;
        this.month=month;
        this.day=day;
    }
    public int getYear() {
        return year;
    }

    public int getMonth() {

        return month;
    }

    public int getDay() {

        return 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(month>12)
            return false;
        if(isLeapYear(year)) {
            if (day > run[month] || year > 2020 || year < 1820 || day < 1 || month < 1) {
                return false;
            } else
                return true;
        }
        else {
            if (day > ping[month] || year > 2020 || year < 1820 || day < 1 || month < 1) {
                return false;
            } else
                return true;
        }
    }

    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 DateUtil getNextNDays(int n){
        while (true){
            if(isLeapYear(year)){
                if(run[month]-day>=n){
                    day=day+n;
                    n = 0;
                    break;
                }
                else {
                    if(month!=12){
                        n=n-(run[month]-day)-1;
                        month++;
                        day=1;
                    }
                    else{
                        n=n-(run[month]-day)-1;
                        day=1;
                        month=1;
                        year++;
                    }

                }
            }
            else {
                if (ping[month] - day >= n) {
                    day = day + n;
                    n = 0;
                    break;
                } else {
                    if (month != 12) {
                        n = n - (ping[month] - day)-1;
                        month++;
                        day = 1;
                    } else {
                        n = n - (ping[month] - day)-1;
                        day = 1;
                        month = 1;
                        year++;
                    }

                }
            }

        }
        DateUtil date1 = new DateUtil(this.year, this.month, this.day);
        return date1;

    }

    public DateUtil getPreviousNDays(int n){
        while(true){
            if(n>=day){
                    if(month>1) {
                        n=n-day;
                        if(!isLeapYear(year))
                            day=ping[month-1];
                        else
                            day=run[month-1];
                        month--;
                    }
                    else {
                        month=12;
                        year--;
                        n=n-day;
                    day=31;}

            }
            else {
                day = day - n;
                break;
            }
        }
        DateUtil date2 = new DateUtil(year, month, day);
        return date2;

    }
    public int num(int year, int month, int day){
        int s = 0;
        for (int i = 1; i < year; i++) {
            if (isLeapYear(i))
                s = s + 366;
            else
                s = s + 365;
        }
        for (int i = 1; i < month; i++) {
            if (isLeapYear(year))
            s = s+run[i];
            else
                s = s+ping[i];
        }
        s = s + day;
        return s;
    }
    public boolean compareDates(DateUtil date) {
        boolean bool = false;
        if (date.getYear() < year)
            bool = true;
        else if (date.getYear() > year)
            bool = false;
        else {
            if (date.getMonth() < month)
                bool = true;
            else if (date.getMonth() > month)
                bool = false;
            else {
                if (date.getDay() < day)
                    bool = true;
                else if (date.getDay() > day)
                    bool = false;

            }
        }
        return bool;
    }
    public boolean equalTwoDates(DateUtil date) {
        if (num(year, month, day) - num(date.getYear(), date.getMonth(), date.getDay())!=0)
            return false;
        else
            return true;
    }
    public int getDaysofDates(DateUtil date)
    {
        int s = num(year, month, day) - num(date.getYear(), date.getMonth(), date.getDay());
        if (s < 0)
            s = -s;
        return s;
    }
    public String showDate(){
        String a;
        a =year+"-"+month+"-"+day;
        return a;
    }
}

(2)解释与心得
首先同7-3这里也要考虑闰年问题,但这里可能跨了几年所以不能只设一个数组再根据年份修改数组,这里我用两个数组来储存。

    private int ping[] = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
    private int run[] = new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};

然后这题同7-3不同的难点是计算相差天数,我把两个日期都同1年1月1日相比得出天数,再相减,得到它们的绝对值即使两个日期的相差天数。

public int num(int year, int month, int day){
        int s = 0;
        for (int i = 1; i < year; i++) {
            if (isLeapYear(i))
                s = s + 366;
            else
                s = s + 365;
        }
        for (int i = 1; i < month; i++) {
            if (isLeapYear(year))
            s = s+run[i];
            else
                s = s+ping[i];
        }
        s = s + day;
        return s;
    }


public int getDaysofDates(DateUtil date)
    {
        int s = num(year, month, day) - num(date.getYear(), date.getMonth(), date.getDay());
        if (s < 0)
            s = -s;
        return s;
    }

三.采坑心得

(1)求下n天或前n天时的逻辑要搞清,我之前先改变了月份和年份再改变的n导致计算错误,应该先改变n再改变月份和年份。

错误代码
while (true){
            if(isLeapYear(year)){
                if(run[month]-day>=n){
                    n = 0;
                    day=day+n;
                    break;
                }
                else {
                    if(month!=12){
                        month++;
                        n=n-(run[month]-day)-1;
                        day=1;
                    }
                    else{
                        day=1;
                        month=1;
                        n=n-(run[month]-day)-1;
                        year++;
                    }

                }
            }
            else {
                if (ping[month] - day >= n) {
                    n = 0;
                    day = day + n;
                    break;
                } else {
                    if (month != 12) {
                        month++;
                        n = n - (ping[month] - day)-1;
                        day = 1;
                    } else {
                        day = 1;
                        month = 1;
                        n = n - (ping[month] - day)-1;
                        year++;
                    }

                }
            }

        }
正确代码
while (true){
            if(isLeapYear(year)){
                if(run[month]-day>=n){
                    day=day+n;
                    n = 0;
                    break;
                }
                else {
                    if(month!=12){
                        n=n-(run[month]-day)-1;
                        month++;
                        day=1;
                    }
                    else{
                        n=n-(run[month]-day)-1;
                        day=1;
                        month=1;
                        year++;
                    }

                }
            }
            else {
                if (ping[month] - day >= n) {
                    day = day + n;
                    n = 0;
                    break;
                } else {
                    if (month != 12) {
                        n = n - (ping[month] - day)-1;
                        month++;
                        day = 1;
                    } else {
                        n = n - (ping[month] - day)-1;
                        day = 1;
                        month = 1;
                        year++;
                    }

                }
            }

        }

(2)题目提供了主函数,题目要求错误日期是返回false我没弄清楚就返回了true。
(3)代码中if-else太多,可以用switch语句代替。

四.改进建议

求相差天数时用的方法,如果相差天数过大,int存不下。

五.总结

经过3次题目集,java总算可以说是刚入门了,之前看到题目明明用c可以轻松解决,用java却束手无策无从下手的情况总算解决了,但语法还是像c语言的,3次题目集下来发现java有许多方便的函数,有些c还简单。java的语法和c语言虽然有些不同但还是有些像,在做题目集时发现很多c的方法可以直接在java中使用,java中的类也和c中的结构体相似,可以通过与c语言的对比来理解java。