OO第一次总结

前言

  这是我的第一篇blog,本学期学习面向对象的程序设计也是我第一次接触到java。由于对java与java语法的不够熟悉,在前几次作业中,闹出一些笑话,也遇到了不少问题。

  第一次作业涉及到了顺序结构、选择结构、循环、数组、字符串等知识点,但是较为基础,主要考察是否熟悉java的基本语法。不过7-10 GPS数据处理这道题需要用到许多我没有涉及过的知识,当时我的选择了放弃,现在想起来还是有些懊悔,是一个比较惨痛的教训。

  第二次作业涉及的知识点与第一次作业类似,难度有所上升,应该还是帮助我们熟悉java中的语法。其中7-8 判断三角形类型 等腰直角三角形测试的这个测试点卡了我很久,上课听到同学们的讨论才知道是浮点数的误差问题。

  第三次作业涉及到了类的定义,getter、setter方法、构造方法的书写,LocalDate类的使用,还需要读类图。虽然这次作业题目量是最少的,但是第一次涉及到类,让我感觉难度突增。不过通过这次作业,我也熟练掌握了怎么构建一个类。

设计与分析

第二次作业

7-9 求下一天

import java.util.*;
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
            System.out.print("Wrong Format");
    }
    public static boolean isLeapYear(int year){
        if((year%4==0&&year%100!=0)||year%400==0)
            return true;
        else
            return false;
    }
    public static boolean checkInputValidity(int year,int month,int day){
        if(year>=1820&&year<=2020){
            if(month==2) {
                if(isLeapYear(year)){
                    if (day >= 1 && day <= 29)
                        return true;
                    else
                        return false;
                }
                else{
                    if (day >= 1 && day <= 28)
                        return true;
                    else
                        return false;
                }
            }
            else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
                if(day>=1&&day<=31)
                    return true;
                else
                    return false;
            }
            else{
                if(day>=1&&day<=30)
                    return true;
                else
                    return false;
            }
        }
        else
            return false;
    }
    public static void nextDate(int year,int month,int day){
        if(month==12&&day==31){
            year+=1;
            month=1;
            day=1;
        }
        else if(month==2){
            if(isLeapYear(year)){
                if(day==29){
                    day=1;
                    month+=1;
                }
                else
                    day+=1;
            }
            else{
                if(day==29){
                    day=1;
                    month+=1;
                }
                else
                    day+=1;
            }
        }
        else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
            if(day==31){
                day=1;
                month+=1;
            }
            else
                day+=1;
        }
        else{
            if(day==30){
                day=1;
                month+=1;
            }
            else
                day+=1;
        }
        System.out.print("Next date is:"+year+"-"+month+"-"+day);
    }
}

  关于这道题,我是使用判断是否为闰年,再判断月份是否为二月,再判断月份是否为大月,再判断日期是否为该月最后一天。单是打出这一连串的判断,我都能体会到最初我算法设计的有多么不合理,如此复杂的代码导致我甚至一度出现了代码长度过限的问题。但当时,由于没有更好的想法,我也只是简单优化了一下if语句,缩短了一些代码长度,使代码可以提交通过测试点就作罢了。

  作业截止后,我与室友交流才发现可以使用数组来存储每个月份的天数,茅塞顿开。通过这道题目我才意识到老师一直强调的沟通交流有多么重要。我也明白了我设计方面存在很大问题,写出的代码质量较低。

第三次作业

7-3 定义日期类

类图

源码

import java.util.*;
public class Main {
    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 Main(){

    }
    public Main(int year,int month,int day){
        this.year=year;
        this.month=month;
        this.day=day;
    }
    public int getYear() {
        return year;
    }
    public void setYear(int year) {
        this.year = year;
    }
    public int getMonth() {
        return month;
    }
    public void setMonth(int month) {
        this.month = month;
    }
    public int getDay() {
        return day;
    }
    public void setDay(int day) {
        this.day = day;
    }
    public boolean isLeapYear(int year){
        if((year%4==0&&year%100!=0)||year%400==0)
            return true;
        else
            return false;
    }
    public boolean checkInputValidity(){
        if(isLeapYear(year))
            mon_maxnum[2]=29;
        if(year<1900||year>2000||month<1||month>12||day<1||day>mon_maxnum[month])
            return false;
        else
            return true;
    }
    public void getNextDate(){
        if(!checkInputValidity())
            System.out.println("Date Format is Wrong");
        else{
            if(month==12&&day==mon_maxnum[month]){
                year++;
                month=1;
                day=1;
            }
            else if(day==mon_maxnum[month]){
                month++;
                day=1;
            }
            else
                day++;
            System.out.println("Next day is:"+year+"-"+month+"-"+day);
        }
    }
    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        int year=input.nextInt();
        int month=input.nextInt();
        int day=input.nextInt();
        Main time=new Main(year,month,day);
        time.getNextDate();
    }
}

  这道题就是第二次作业中 7-9 求下一天 的迭代升级,但是需要定义一个date类,不过老师在题目中给出了类图,帮我们做好了类的设计,为我们提供了一定的思路,比如直接给出了属性mon_maxnum数组,提示我们可以使用数组存放每个月的天数,加上上次作业的经验,写这道题时我感觉较为轻松。

 

7-4 日期类设计

类图

源码

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

    }
    public DateUtil(int year,int month,int day){
        this.day=day;
        this.month=month;
        this.year=year;
    }
    public int getDay() {
        return day;
    }

    public int getMonth() {
        return month;
    }

    public int getYear() {
        return year;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public void setMonth(int month) {
        this.month = month;
    }
    public boolean isLeapYear(int year){
        if((year%4==0&&year%100!=0)||year%400==0)
            return true;
        else
            return false;
    }
    public boolean checkInputValidity(){
        if(isLeapYear(year))
            mon_maxnum[2]=29;
        if(year<1820||year>2020||month<1||month>12||day<1||day>mon_maxnum[month])
            return false;
        else
            return true;
    }
    public DateUtil getNextNDays(int n) {
        int year1=year,month1=month,day1=day;
        int year_max=365;
        if(isLeapYear(year1)) {
            year_max = 366;
            mon_maxnum[2]=29;
        }
        while(n>=year_max){
            if(isLeapYear(year1)) {
                year_max = 366;
                mon_maxnum[2]=29;
            }
            else{
                year_max=365;
                mon_maxnum[2]=28;
            }
            n-=year_max;
            year1++;
        }
        while (n>=mon_maxnum[month1]){
            n-=mon_maxnum[month1];
            month1++;
            if(month1>12){
                year1++;
                month1-=12;
            }
        }
        if(day1+n>mon_maxnum[month1]){
            day1+=n-mon_maxnum[month1];
            month1++;
        }
        else
            day1+=n;
        DateUtil date=new DateUtil(year1,month1,day1);
        return date;
    }
    public DateUtil getPreviousNDays(int n){
        int year1=year,month1=month,day1=day;
        int year_max=365;
        if(isLeapYear(year1))
            mon_maxnum[2]=29;
        while(n>=year_max){
            if(isLeapYear(year1))
                mon_maxnum[2]=29;
            else{
                mon_maxnum[2]=28;
            }
            n-=year_max;
            year1--;
        }
        while (n>=mon_maxnum[month1]){
            n-=mon_maxnum[month1];
            month1--;
            if(month1<1){
                year1--;
                month1=12;
            }
        }
        if(day1-n<=0){
            month1--;
            n-=day1;
            day1=mon_maxnum[month1]-n;
        }
        else
            day1-=n;
        if(month1<1){
            year1--;
            month1=12;
        }
        DateUtil date=new DateUtil(year1,month1,day1);
        return date;
    }
    public boolean equalTwoDates(DateUtil date){
        if(year== date.getYear()&&month== date.getMonth()&&day==date.getDay())
            return true;
        else
            return false;
    }
    public boolean compareDates(DateUtil date){
        if(year>date.getYear())
            return true;
        else if(year<date.getYear())
            return false;
        else{
            if(month> date.getMonth())
                return true;
            else if (month<date.getMonth())
                return false;
            else{
                if(day> date.getMonth())
                    return true;
                else
                    return false;
            }
        }
    }
    public int getDaysofDates(DateUtil date){
        int n=0;
        int year1,year2,month1,month2,day1,day2;
        if(equalTwoDates(date))
            return n;
        if (compareDates(date)) {
            year2=year;
            month2=month;
            day2=day;
            day1=date.getDay();
            month1=date.getMonth();
            year1=date.getYear();
        }
        else{
            year1=year;
            month1=month;
            day1=day;
            day2=date.getDay();
            month2=date.getMonth();
            year2=date.getYear();
        }
        while (year1+1<year2){
            if(isLeapYear(year1)&&month1<=2)
                n+=366;
            else
                n+=365;
            year1++;
        }
        while (month1<12){
            n+=mon_maxnum[month1];
            month1++;
        }
        n+=mon_maxnum[12]-day1;
        int i=1;
        while (i<month2){
            n+=mon_maxnum[i];
            i++;
        }
        n+=day2;
        return n;
    }
    public String showDate(){
        String year1=Integer.toString(year);
        String month1=Integer.toString(month);
        String day1=Integer.toString(day);
        String date=year1+"-"+month1+"-"+day1;
        return date;
    }
}

  这道题作为上一题的迭代升级版,虽然老师也帮我们做完了类的设计,给出了要编写的方法,但还是把我难住了。有着前两次算下一天的经验,算下n天虽然稍微复杂一些,我在思考并于室友讨论后完成了。但是依照相同思路写计算前n天功能出现了一些问题,导致计算日期总会有几天的偏差。并且因为对题目难度没有很好的认识,我仅仅在截止当天的傍晚才开始着手写这道题目,导致最后我没有充足的时间来完善我计算前n天与算两日期相差天数功能的代码,这道题目只拿到了一部分分数,这给我了一个惨痛的教训,我需要端正我对待作业的态度,要认识到java不同于上学期的C语言,即使在截止的当天,只要努努力就能写完。对于以后的java作业,我会更早动手,拿出精益求精的态度来对待。

踩坑心得

部分题目已经在上一部分分析过,这里就不再重复了。

第一次作业

7-1

  作为学习java以来做的第一道题目,出现了不少低级问题,例如不知道主方法所在的类必须命名为Main,当时多次提交也完全没发现问题出在哪里。也不知道要用import来引入包。

 

 

 

  除开简单的语法错误,我还不清楚java中也可以使用printf输出来保留小数,但是需要注意java中%需要使用%%。

7-2

  忽略了题目给出的输入顺序,导致出现错误。

 

 

 

7-3

  没有注意到题目给出图片与输出样例格式不同导致错误。

 7-5

  不知道java中字符串为常量,需要使用StringBuilder才能修改。

 7-7

  使用了嵌套for循环来寻找数组中重复的元素,出现运行超时的错误。

 

   更换了一种方法后,不会运行超时,但是出现了非零返回的错误,搜索后知道可能是数组越界导致的,发现使用的方法在数组元素过大时很容易出现越界的错误。

 

 

 

 

第二次作业

7-1

  答案错误,但是将double类型数据强制转换为float后答案就正确了。在7-3中也出现了这种问题。

 

 

 

 7-8

  在两浮点数之间用了==,忽略了浮点数精度导致的误差。

 

 

 

 7-9

  算法设计过于复杂。

  忽视了是否闰年的二月、是否大小月,输入的合法范围不同,需要分开判断。

第三次作业

7-1

  不熟悉类的定义,getter、setter、构造方法的书写。忽略了除主类外,其他类不能使用public等修饰符。

改进建议

  1.代码不爱写注释,可读性不强,别人、甚至我自己隔一段时间看我代码的时候,总要花上一段时间才知道这段代码的功能是什么。需要培养边写代码边注释的习惯。

  2.代码书写不够规范,需要牢记阿里的代码规范。

  3.与同学交流不够,很多自己找不出的bug或者思路有误的题目,和同学简单交流一下,很快就能得到解决,还有助于拓展自己的知识面,拓宽思路。

  4.对java中的许多类不了解,需要多看教材并在网上学习。

  5.对待作业不能再拖延,一发布就要着手去做。

总结

  通过这三次作业,我学习到了很多,也发现自己的不足,算是开始入门java了。对老师上课不讲的知识,要多看配套的慕课系统性的学习。自己也要培养好的学习习惯,多掌握一些java知识,为之后基于java的专业课学习打基础。

posted @ 2023-03-26 15:26  LastXuan  阅读(22)  评论(0)    收藏  举报