第一次作业报告
一.前言
第一次做作业报告,可能不太规范和清楚,请多多指教。
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”格式返回日期值
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用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。