OOP第一阶段(前四周)作业总结

OOP第一阶段(前四周)作业总结

一、前言

在第一阶段作业中,三次训练集得分依次是88、100、100。
由于在第一周之前完全没接触过Java,就导致在写训练集01时感到非常吃力,一边在MOOC上观看翁恺老师的零基础学Java语言课程,一边还要去搜索碎片化的Java知识点以完成作业,但好在题目总体来说比较基础,只有7-10GPS数据处理题较难一些,还是在截止时间之前完成了此次作业。
训练集01和训练集02主要考察的是Java基础语法知识,比如if & if else & else 语句、for & while 循环、对字符串的操作等,以及简单的逻辑思维能力,如训练集02的7-6 巴比伦法求平方根近似值就需要用到逻辑思维进行计算并判断跳出循环。
训练集02最后一题7-9 求下一天就过渡到了Java方法的使用,需要建立一些方法判断输入的日期是否合法、判断是否为闰年以及求输入日期的下一天。
训练集03就到了Java类的创建,要求和编写类,创建类的属性、属性的getter和setter方法其他能实现功能的方法,以及在别的函数中调用类方法。训练集03虽然题量只有四题,但是是第一阶段作业最难的一次训练集,也是我踩坑最多的一次,但反过来也是我编写Java代码成长最快的一次。

总的来说,第一阶段作业题量总体适中,有较充足的时间完成每周的作业,每一次题目集难度依次提升。

二、设计与分析

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

输出格式:

  • 当输入数据非法及输入日期不存在时,输出“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类,建立Date类的属性year, month, day并修饰权限修饰符private,

class Date {
    private int year;
    private int month;
    private int day;
}

然后建立类中的各种方法,getters获取属性, setters修改属性以及isLeapYear判断是否为闰年, checkInputValidity判断输入日期是否合法, getNextDate获取下一天。

public Date(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) {
    return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}

public boolean checkInputValidity() {
    if (isLeapYear(year)) {
        if (mon_maxnum[2] == 28) {
            mon_maxnum[2] = 29;
        }
    } else {
        if (mon_maxnum[2] == 29) {
            mon_maxnum[2] = 28;
        }
    }
    if (year >= 1900 && year <= 2000 && month >= 1 && month <= 12 && day >= 1 && day <= mon_maxnum[month]) {
        return true;
    } else {
        return false;
    }
}

public void getNextDate() {
    day++;
    if (day > mon_maxnum[month]) {
        day -= mon_maxnum[month];
        month += 1;
    }
    if (month > 12) {
        month -= 12;
        year += 1;
    }
}

创建完Date类之后就在Main类中输入日期信息并输出下一天日期信息。

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    Date date = new Date();
    date.Date(in.nextInt(), in.nextInt(), in.nextInt());
    if (date.checkInputValidity()) {
        date.getNextDate();
        System.out.println("Next day is:" + date.getYear() + "-" + date.getMonth() + "-" + date.getDay());
    } else {
        System.out.println("Date Format is Wrong");
    }
    in.close();
}

类图

完整代码如下

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		Date date = new Date();
		date.Date(in.nextInt(), in.nextInt(), in.nextInt());
		if (date.checkInputValidity()) {
			date.getNextDate();
			System.out.println("Next day is:" + date.getYear() + "-" + date.getMonth() + "-" + date.getDay());
		} else {
			System.out.println("Date Format is Wrong");
		}
        in.close();
	}
}

class Date {
	private int year;
	private int month;
	private int day;
	int[] mon_maxnum = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	public Date() {
	}

	public void Date(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) {// 判断year是否为闰年
		if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
			return true;
		} else {
			return false;
		}
	}

	public boolean checkInputValidity() { // 检测输入的年、月、日是否合法
		if (isLeapYear(year)) {
			if (mon_maxnum[2] == 28) {
				mon_maxnum[2] = 29;
			}
		} else {
			if (mon_maxnum[2] == 29) {
				mon_maxnum[2] = 28;
			}
		}
		if (year >= 1900 && year <= 2000 && month >= 1 && month <= 12 && day >= 1 && day <= mon_maxnum[month]) {
			return true;
		} else {
			return false;
		}
	}

	public void getNextDate() { // 取得一天后的日期
		day++;
		if (day > mon_maxnum[month]) {
			day -= mon_maxnum[month];
			month += 1;
		}
		if (month > 12) {
			month -= 12;
			year += 1;
		}
	}
}

OOP训练集03 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,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

设计与分析
这一题相较于上一题较难,是上一题的迭代
同样也是先创建你DateUtil类,建立DateULtil类的属性year, month, day并修饰权限修饰符private

class DateUtil {
    private int year;
    private int month;
    private int day;
}

然后建立类中的各种方法,getters获取属性, setters修改属性以及isLeapYear判断是否为闰年, checkInputValidity判断输入日期是否合法, isLeapYear判断是否为闰年,getNextDays获取n天后日期,getPreviousDays获取n天前日期,compareDates比较日期大小,equalTwoDates判断两个日期是否相等,getDaysofDates求两个日期之间相差的天数,showDate以"year-month-day"格式输出日期。
代码详见完整代码

在编写getNextDays与getPreviousDays方法时,我采取的时按年、按月再按日的方式获取n天后或n天前信息,而不是简单地迭代OOP训练集03 7-3定义日期类,将求一天后延展到求n天后,这样做能使得代码时间复杂度更低,运行n很大是速度较快

public DateUtil getNextNDays(int n) {
    if (isLeapYear(year) && month == 2 && day == 29) {
        n++;
    }
    while (true) {
        if (isLeapYear(year)) {
            if (n > 366) {
                n -= 366;
                year++;
            } else {
                break;
            }
        } else {
            if (n > 365) {
                n -= 365;
                year++;
            } else {
                break;
            }
        }
    }
    if ((isLeapYear(year) && month > 2)) {
        n--;
    }
    while (true) {
        if (isLeapYear(year)) {
            if (n > mon_maxnum[month]) {
                n -= mon_maxnum[month];
                month++;
                if (month > 12) {
                    year++;
                    month -= 12;
                }
            } else {
                break;
            }
        } else {
            if (n > mon_maxnum[month]) {
                n -= mon_maxnum[month];
                month++;
                if (month > 12) {
                    year++;
                    month -= 12;
                }
            } else {
                break;
            }
        }
    }
    day += n;
    if (day > mon_maxnum[month]) {
        day -= mon_maxnum[month];
        month++;
        if (month > 12) {
            year++;
            month -= 12;
        }
    }
    return this;
}

编写getDaysofDates方法时,最开始的思路是直接计算两个日期之间的天数,但在实现代码时发现这种方式十分复杂,于是就采取间接的方式计算两个日期之间的天数——分别求出两个日期与1年1月1号之间的天数,再作差就能得到这两个日期之间的天数,用这样的方式就会更容易求得结果。

public int getDaysofDates(DateUtil date) {
    int sum1 = 0;
    for (int i = 1; i < this.year; i++) {
        sum1 += 365;
        if (isLeapYear(i)) {
            sum1++;
        }
    }
    for (int i = 1; i < this.month; i++) {
        sum1 += mon_maxnum[i];
        if (i == 2 && isLeapYear(this.year)) {
            sum1++;
        }
    }
    sum1 += this.day;
    int sum2 = 0;
    for (int i = 1; i < date.year; i++) {
        sum2 += 365;
        if (isLeapYear(i)) {
            sum2++;
        }
    }
    for (int i = 1; i < date.month; i++) {
        sum2 += mon_maxnum[i];
        if (i == 2 && isLeapYear(date.year)) {
            sum2++;
        }
    }
    sum2 += date.day;
    return sum2 - sum1;
}

类图

完整代码如下


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;
    int[] mon_maxnum = { 0, 31, 28, 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 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 checkInputValidity() {// 检测输入的年、月、日是否合法
        if (isLeapYear(year)) {
            if (mon_maxnum[2] == 28) {
                mon_maxnum[2] = 29;
            }
        } else {
            if (mon_maxnum[2] == 29) {
                mon_maxnum[2] = 28;
            }
        }
        return year >= 1820 && year <= 2020 && month >= 1 && month <= 12 && day >= 1 && day <= mon_maxnum[month];
    }

    public boolean isLeapYear(int year) {// 判断year是否为闰年
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            mon_maxnum[2] = 29;
            return true;
        } else {
            mon_maxnum[2] = 28;
            return false;
        }
    }

    public DateUtil getNextNDays(int n) {// 取得year-month-day的下n天日期
        if (isLeapYear(year) && month == 2 && day == 29) {
            n++;
        }
        while (true) {
            if (isLeapYear(year)) {
                if (n > 366) {
                    n -= 366;
                    year++;
                } else {
                    break;
                }
            } else {
                if (n > 365) {
                    n -= 365;
                    year++;
                } else {
                    break;
                }
            }
        }
        if ((isLeapYear(year) && month > 2)) {
            n--;
        }
        while (true) {
            if (isLeapYear(year)) {
                if (n > mon_maxnum[month]) {
                    n -= mon_maxnum[month];
                    month++;
                    if (month > 12) {
                        year++;
                        month -= 12;
                    }
                } else {
                    break;
                }
            } else {
                if (n > mon_maxnum[month]) {
                    n -= mon_maxnum[month];
                    month++;
                    if (month > 12) {
                        year++;
                        month -= 12;
                    }
                } else {
                    break;
                }
            }
        }
        day += n;
        if (day > mon_maxnum[month]) {
            day -= mon_maxnum[month];
            month++;
            if (month > 12) {
                year++;
                month -= 12;
            }
        }
        return this;
    }

    public DateUtil getPreviousNDays(int n) {// 取得year-month-day的前n天日期
        while (true) {
            if ((isLeapYear(year) && month > 2) || (isLeapYear(year - 1) && month < 3)) {
                if (n >= 366) {
                    n -= 366;
                    year--;
                } else {
                    break;
                }
            } else {
                if (n >= 365) {
                    n -= 365;
                    year--;
                } else {
                    break;
                }
            }
        }
        if (isLeapYear(year) && month > 2) {
            n++;
        }
        while (true) {
            if (isLeapYear(year)) {
                if (month - 1 == 0) {
                    if (n > mon_maxnum[12]) {
                        n -= mon_maxnum[12];
                        year--;
                        month += 11;
                    } else {
                        break;
                    }
                } else {
                    if (n > mon_maxnum[month - 1]) {
                        n -= mon_maxnum[month - 1];
                        month--;
                    } else {
                        break;
                    }
                }
            } else {
                if (month - 1 == 0) {
                    if (n > mon_maxnum[12]) {
                        n -= mon_maxnum[12];
                        year--;
                        month += 11;
                    } else {
                        break;
                    }
                } else {
                    if (n > mon_maxnum[month - 1]) {
                        n -= mon_maxnum[month - 1];
                        month--;
                    } else {
                        break;
                    }
                }
            }
        }
        day -= n;
        if (day <= 0) {
            if (month - 1 <= 0) {
                year--;
                month += 12;
            }
            day += mon_maxnum[month - 1];
            month--;
            if (isLeapYear(year) && month == 2) {
                day++;
            }
        }
        return this;
    }

    public boolean compareDates(DateUtil date) {// 比较当前日期与date的大小(先后)
        if (this.year > date.year) {
            return true;
        } else if (this.year == date.year && this.month > date.month) {
            return true;
        } else
            return this.year == date.year && this.month == date.month && this.day > date.day;
    }

    public boolean equalTwoDates(DateUtil date) {// 判断两个日期是否相等
        return this.year == date.year && this.month == date.month && this.day == date.day;
    }

    public int getDaysofDates(DateUtil date) {// 求当前日期与date之间相差的天数
        int sum1 = 0;
        for (int i = 1; i < this.year; i++) {
            sum1 += 365;
            if (isLeapYear(i)) {
                sum1++;
            }
        }
        for (int i = 1; i < this.month; i++) {
            sum1 += mon_maxnum[i];
            if (i == 2 && isLeapYear(this.year)) {
                sum1++;
            }
        }
        sum1 += this.day;
        int sum2 = 0;
        for (int i = 1; i < date.year; i++) {
            sum2 += 365;
            if (isLeapYear(i)) {
                sum2++;
            }
        }
        for (int i = 1; i < date.month; i++) {
            sum2 += mon_maxnum[i];
            if (i == 2 && isLeapYear(date.year)) {
                sum2++;
            }
        }
        sum2 += date.day;
        return sum2 - sum1;
    }

    public String showDate() {// 以“year-month-day”格式返回日期值
        return year + "-" + month + "-" + day;
    }
}

三、踩坑心得

  • OOP训练集01 7-8从一个字符串中移除包含在另一个字符串中的字符
    题目:从一个字符串中移除包含在另一个字符串中的字符。输入两行字符串,将第一行字符串中包括第二行字符串中的所有字母去除。输出去除后保留的字符串。
    踩坑与心得:从一个字符串中移除包含在另一个字符串中的字符时,错误地使用String java.lang.String.replace(char oldChar, char newChar)方法

    str1 = str1.replace(str2.charAt(i), '');
    

    运行后编译器报错:Invalid character constant,翻译成中文就是无效字符常量。看到报错后我便明白,空字符应该为'\0', 而不是''。

    发现了后,将代码修改如下

    str1 = str1.replace(str2.charAt(i), '\0');
    
    import java.util.Scanner;
    
    public class Main {
      public static void main(String[] args) {
          Scanner in = new Scanner(System.in);
          String str1 = in.nextLine();
          String str2 = in.nextLine();
          for (int i = 0; i < str2.length(); i++) {
              str1 = str1.replace(str2.charAt(i), '\0'); // 正确代码
          }
          System.out.println(str1);
          in.close();
      }
    }
    

    修改后结果为

  • OOP训练集02 7-8判断三角形

  • 题目:输入三角形三条边,判断该三角形为什么类型的三角形。
    踩坑与心得在对直角三角形进行判断时,未考虑到精读问题,直接使用a * a + b * b == c * c || a * a + c * c == b * b的方式进行判断直角三角形

    import java.util.Scanner;
    
    public class Main {
      public static void main(String[] args) {
          Scanner in = new Scanner(System.in);
          float a = in.nextFloat();
          float b = in.nextFloat();
          float c = in.nextFloat();
          if (a < 1 || a > 200 || b < 1 || b > 200 || c < 1 || c > 200) {
              System.out.print("Wrong Format");
          } else {
              if (a + b <= c || a + c <= b || b + c <= a) {
                  System.out.print("Not a triangle");
              } else {
                  if (a == b || a == c || b == c) {
                      if (a == b && a == c) {
                          System.out.println("Equilateral triangle");
                      } else if (a * a + b * b == c * c || a * a + c * c == b * b) { //错误地判断直角三角形
                          System.out.println("Isosceles right-angled triangle");
                      } else {
                          System.out.println("Isosceles triangle");
                      }
                  } else {
                      if (a * a + b * b == c * c || a * a + c * c == b * b) { // 错误地判断直角三角形
                          System.out.println("Right-angled triangle");
                      } else {
                          System.out.println("General triangle");
                      }
                  }
              }
          }
          in.close();
      }
    }
    

    导致我在输入根号2、根号3、根号5时,预期的输出结果应该为Right-angled triangle,但实际输出结果却为General triangle,很明显是没考虑数据精读问题导致的错误

    发现错误后,将判断直角三角形的语句改为如下:

    Math.abs(a * a + b * b - c * c) < 0.1 || Math.abs(a * a + b * b - c * c) < 0.1 || Math.abs(b * b + c * c - a * a) < 0.1)
    

    完整代码如下:

    import java.util.Scanner;
    
    public class Main {
      public static void main(String[] args) {
          Scanner in = new Scanner(System.in);
          float a = in.nextFloat();
          float b = in.nextFloat();
          float c = in.nextFloat();
          if (a < 1 || a > 200 || b < 1 || b > 200 || c < 1 || c > 200) {
              System.out.print("Wrong Format");
          } else {
              if (a + b <= c || a + c <= b || b + c <= a) {
                  System.out.print("Not a triangle");
              } else {
                  if (a == b || a == c || b == c) {
                      if (a == b && a == c) {
                          System.out.println("Equilateral triangle");
                      } else if (Math.abs(a * a + b * b - c * c) < 0.1 || Math.abs(a * a + b * b - c * c) < 0.1
                              || Math.abs(b * b + c * c - a * a) < 0.1) {
                          System.out.println("Isosceles right-angled triangle");
                      } else {
                          System.out.println("Isosceles triangle");
                      }
                  } else {
                      if (Math.abs(a * a + b * b - c * c) < 0.1 || Math.abs(a * a + b * b - c * c) < 0.1
                              || Math.abs(b * b + c * c - a * a) < 0.1) {
                          System.out.println("Right-angled triangle");
                      } else {
                          System.out.println("General triangle");
                      }
                  }
              }
          }
          in.close();
      }
    }
    

    此时再输入根号2、根号3、根号5就可以得到正确结果Right-angled triangle

  • OOP训练集03 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”格式返回日期值
    

    踩坑与心得此题难度较大,踩到的坑比较多
    ①.首先就是闰年2月有29日而平年2月只有28日问题,这是个简单的错误,但开始的时候考虑还不完全,在写isLeapYear(int year)方法时没在判断闰年和平年时修改2月的最大天数

    public boolean isLeapYear(int year) {
      return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    }
    

    就导致了在输入日期信息2 2004 2 29 366时,输出Wromg Format,很明显是错的,所以在这个错误一出现后,立刻就修改好了

    public boolean isLeapYear(int year) {
      if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
      mon_maxnum[2] = 29;
      return true;
      } else {
          mon_maxnum[2] = 28;
          return false;
      }
    }
    

    ②.跨越天数大时,导致无法得到正确的日期,比如在计算1999年3月28号后6543天的日期,得到的结果与预期的结果相差一天。

    这是由于在进行以年为单位的日期计算时,未考虑周到跨越闰年个数的情况。

    while (true) {
      if (isLeapYear(year)) {
          if (n > 366) {
              n -= 366;
              year++;
          } else {
              break;
          }
      } else {
          if (n > 365) {
              n -= 365;
              year++;
          } else {
              break;
          }
      }
    }
    

    以上情况就是少计算了一个闰年2016,就导致实际得到的结果比预期结果往后了一天,于是我修改为如下代码:

    while (true) {
      if (isLeapYear(year)) {
          if (n > 366) {
              n -= 366;
              year++;
          } else {
              break;
          }
      } else {
          if (n > 365) {
              n -= 365;
              year++;
          } else {
              break;
          }
      }
    }
    if ((isLeapYear(year) && month > 2)) {
      n--;
    }
    

    提交修改后代码后,通过了所有的测试用例,但这时还没完,之后我回看这份代码时,输入了一个十分特殊的测试用例:

    2004年2月29日的366天后怎么会是2005年2月28日呢?带着疑问调试代码,发现进入isLeapYear(int year)方法判断完2004年是闰年,将2月的最大天数修改为29天后,n的值减为0,year加一年从2004年到2005年,由于n为0,后面就不会在对年进行是否为闰年的判断,就引起了这次错误。
    修改代码如下:

    if (isLeapYear(year) && month == 2 && day == 29) {
      n++;
    }
    while (true) {
      if (isLeapYear(year)) {
          if (n > 366) {
              n -= 366;
              year++;
          } else {
              break;
          }
      } else {
          if (n > 365) {
              n -= 365;
              year++;
          } else {
              break;
          }
      }
    }
    if ((isLeapYear(year) && month > 2)) {
      n--;
    }
    

    这是再对以上测试用例进行判断后,得到的正确的答案

四、改进建议

编码的时候应该摒弃C语言的编码习惯,现在处于C语言到Java的过渡期,在编码习惯上还是与C语言有很多相似之处,主要原因就在于学习Java时间还不长,对Java方法的了解不多,就导致有很多方便的Java方法不会用。此外,也要摒弃面向过程的编码思想,逐渐从面向过程到面向对象过渡。因此就需要在后续的学习中学习更多Java方面的知识,学习并熟悉面向对象,具体就是继续上后续的Java网课以及听老师讲课,多多刷题。

五、总结

进过这三周的Java学习,在老师的教导,网课的学习以及训练集的推动下,快速地熟悉了Java的基础语法知识,熟悉了Java方法的创建以及Java方法的调用,还熟悉了Java类的创建,private, public, protected等权限修饰符对类中属性的修饰,getters, setters对类中属性的获取和修改。编程思想已然初步从面向过程向面向对象转变。
由于时间紧,时间仅有三周,再加上是从0开始学习Java,老师上课不讲Java的基础知识,直接开始讲建模技术,这样的上课方式有利也有弊吧,对于这三周来说,上课节奏难以跟上,上课讲到的许多内容没听懂,只是知道了个大概,好处就是在这样的压力之下快速地学会了基础的Java编程的能力。

posted @ 2023-03-25 23:08  Vousêtesunique  阅读(70)  评论(0)    收藏  举报