(1)前言:这三次题目集综合考察了程序设计基本的数据输入输出,选择,循环,数组,字符,字符串,方法以及类和对象的使用。题量共有15题,大多数为简单题有个别难题。
(2)设计与分析: (题目集1较简单就不分析了) 1.题目集2 7-2(串口字符解析)较简单。RS232是串口常用的通信协议,在异步通信模式下,串口可以一次发送5~8位数据,收发双方之间没有数据发送时线路维持高电平,相当于接收方持续收到数据“1”(称为空闲位),发送方有数据发送时,会在有效数据(5~8位,具体位 数由通信双方提前设置)前加上1位起始位“0”,在有效数据之后加上1位可选的奇偶校验位和1位结束位“1”。请编写程序,模拟串口接收处理程序,注:假定有效数据是8 位,奇偶校验位采用奇校验。
输入格式:
由0、1组成的二进制数据流。例如:11110111010111111001001101111111011111111101111
输出格式:
过滤掉空闲、起始、结束以及奇偶校验位之后的数据,数据之前加上序号和英文冒号。
如有多个数据,每个数据单独一行显示。
若数据不足11位或者输入数据全1没有起始位,则输出"null data",
若某个数据的结束符不为1,则输出“validate error”。
若某个数据奇偶校验错误,则输出“parity check error”。
若数据结束符和奇偶校验均不合格,输出“validate error”。
如:11011或11111111111111111。
例如:
1:11101011
2:01001101
3:validate error
踩坑心得:.next()不可以接收空格,.nextLine()可以接收空格。需要先把数据前的空闲位1跳过,然后找到起始位0,之后的8位为有效数据,再之后的两个位是奇偶校验位和结束位,
结束位一定为1不然直接输出“validate error”,奇偶校验位采用奇校验,就是8位有效数据加奇偶校验位的和为奇数才是正确的。还需要先判断起始位后是否有11位数据。
代码如下:
1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 Scanner in = new Scanner(System.in); 7 String s=in.nextLine(); 8 int i=0,j=0,k=0,n=1; 9 char a='1'; 10 11 12 for(i=0;i<s.length();i++) {//找到起始位 13 if(s.charAt(i)=='0') { 14 j=1; 15 break; 16 } 17 } 18 i=0; 19 if(j!=1||s.length()<11) System.out.println("null data");//是否有11位 20 else while(true) { 21 for(;i<s.length();i++) {//把前面空闲位“1”跳过 22 if(s.charAt(i)=='0') break; 23 } 24 k++; 25 j=0; 26 n=0; 27 if(s.length()>=i+10) {//后面是否还有11位 28 29 while(true) { 30 if(s.charAt(i+n)=='1') j++;//计算1的个数 31 n++; 32 if(n==9) break;//有效结束 33 } 34 if(j%2==1) a='0';//奇偶判断偶1奇0 35 else a='1'; 36 37 if(s.charAt(i+10)=='0') System.out.println(k+":validate error");//结束符判断 38 else if(s.charAt(i+9)!=a) System.out.println(k+":parity check error");//奇偶判断 39 else System.out.println(k+":"+s.charAt(i+1)+s.charAt(i+2)+s.charAt(i+3)+s.charAt(i+4)+s.charAt(i+5)+s.charAt(i+6)+s.charAt(i+7)+s.charAt(i+8)); 40 } 41 else break; 42 43 i=i+11; 44 45 } 46 47 } 48 49 } 2.题目集3 7-1(用类解一元二次方程式)简单无坑。 直接返回公式即可。 import java.util.Scanner; public class Main { public static void main(String[] args){ Scanner input = new Scanner(System.in); double a = Double.parseDouble(input.next()); double b = Double.parseDouble(input.next()); double c = Double.parseDouble(input.next()); if(a == 0){ System.out.println("Wrong Format"); System.exit(0); } //create a QuadraticEquation object QuadraticEquation equation = new QuadraticEquation(a, b, c); //get value of b * b - 4 * a * c double discriminant = equation.getDiscriminant(); System.out.println("a=" + equation.getA() + ",b=" + equation.getB() + ",c=" + equation.getC()+":"); if (discriminant < 0) { System.out.println("The equation has no roots."); } else if (discriminant == 0) { System.out.println("The root is " + String.format("%.2f", equation.getRoot1())); } else // (discriminant >= 0) { System.out.println("The roots are " + String.format("%.2f", equation.getRoot1()) + " and " + String.format("%.2f", equation.getRoot2())); } } } class QuadraticEquation{ //your code private double a; private double b; private double c; public QuadraticEquation() { super(); // TODO 自动生成的构造函数存根 } public QuadraticEquation(double a, double b, double c) { super(); this.a = a; this.b = b; this.c = c; } public double getA() { return a; } public void setA(double a) { this.a = a; } public double getB() { return b; } public void setB(double b) { this.b = b; } public double getC() { return c; } public void setC(double c) { this.c = c; } public double getDiscriminant() { return b*b-4*a*c; } public double getRoot1() { return ((-b)+Math.pow(getDiscriminant(), 0.5))/(2*a); } public double getRoot2() { return ((-b)-Math.pow(getDiscriminant(), 0.5))/(2*a); } }
输入一个由英文字母组成的字符串(大小写均可),将所有英文字母转换成它们在字母表中的序号,例如:“AbbcD”转换为“12234”。
输入格式:
由英文字母组成的字符串(大小写均可)。例如:“AbbcD”
若包含非英文字母,视为非法输入。
输出格式:
所有英文字母转换成它们在字母表中的序号,例如:“12234”。
非法输入输出"Wrong Format".
踩坑心得:单个字符要用单引号‘ ’ 如:‘a'. 需要先判断输入的字符是否在a~z 或 A~Z 之间。设计一个类中的方法 传入一个字符可返回相应的数字。
代码如下:
1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 Scanner in = new Scanner(System.in); 7 String i=in.nextLine(); 8 int k=0,j=0; 9 Pro Aa = new Pro(); 10 11 for(j = 0;j<i.length();j++) { 12 if((i.charAt(j)>='a'&&i.charAt(j)<='z')||i.charAt(j)>='A'&&i.charAt(j)<='Z') k=1; 13 else { 14 k=0; 15 break; 16 } 17 } 18 if(k!=1) System.out.println("Wrong Format"); 19 else { 20 for(j=0;j<i.length();j++) 21 System.out.printf("%d",Aa.return1(i.charAt(j))); 22 } 23 24 } 25 26 } 27 28 class Pro{ 29 private int i=0; 30 31 public Pro(){ 32 } 33 34 public int return1(char a) { 35 if(a=='a'||a=='A') i=1; 36 else if(a=='b'||a=='B') i=2; 37 else if(a=='c'||a=='C') i=3; 38 else if(a=='d'||a=='D') i=4; 39 else if(a=='e'||a=='E') i=5; 40 else if(a=='f'||a=='F') i=6; 41 else if(a=='g'||a=='G') i=7; 42 else if(a=='h'||a=='H') i=8; 43 else if(a=='i'||a=='I') i=9; 44 else if(a=='j'||a=='J') i=10; 45 else if(a=='k'||a=='K') i=11; 46 else if(a=='l'||a=='L') i=12; 47 else if(a=='m'||a=='M') i=13; 48 else if(a=='n'||a=='N') i=14; 49 else if(a=='o'||a=='O') i=15; 50 else if(a=='p'||a=='P') i=16; 51 else if(a=='q'||a=='Q') i=17; 52 else if(a=='r'||a=='R') i=18; 53 else if(a=='s'||a=='S') i=19; 54 else if(a=='t'||a=='T') i=20; 55 else if(a=='u'||a=='U') i=21; 56 else if(a=='v'||a=='V') i=22; 57 else if(a=='w'||a=='W') i=23; 58 else if(a=='x'||a=='X') i=24; 59 else if(a=='y'||a=='Y') i=25; 60 else if(a=='z'||a=='Z') i=26; 61 62 return i; 63 } 64 }
3.题目集3 7-2(日期类设计)
参考题目集二中和日期相关的程序,设计一个类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中提供的任何与日期相关的类与方法,需要自己设计相关方法。
踩坑心得:特别注意闰年会多一天,比较两个日期的大小时可用这两个日期到同一天(如 1800 1 1)的天数相减。判断是否为闰年(year%4==0&&year%100!=0)||year%400==0),,
闰年求前n天和后n天时需要判断是否在2月29号前后。判断下n天和前n天要注意有多种情况:年的+-1, 月的+-1,闰年二月29的+-1.
代码如下:
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; public DateUtil() { super(); // TODO 自动生成的构造函数存根 } public DateUtil(int year, int month, int day) { super(); 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)&&month==2&&day>28)||year>2020||year<1820||month>12||month<1||day>31||day<1||(month==4&&day>30)||(month==6&&day>30)||(month==9&&day>30)||(month==11&&day>30)) return false; else return true; } public boolean isLeapYear(int year){//判断year是否为闰年 if((year%4==0&&year%100!=0)||year%400==0) return true; else return false; } public DateUtil getNextNDays(int n){//取得year-month-day的下n天日期 int year1=year,month1=month,day1=day; for(;n>0;n--) { while(n>366) { if(isLeapYear(year1)) n=n-366; else n=n-365; year1=year1+1; } if(month1==12&&day1==31) { year1=year1+1; month1=1; day1=1; } else if((month1==1||month1==3||month1==5||month1==7||month1==8||month1==10)&&day1==31) { month1=month1+1; day1=1; } else if((month1==4||month1==6||month1==9||month1==11)&&day1==30) { month1=month1+1; day1=1; } else if(isLeapYear(year1)&&month1==2&&day1==29) { month1=3; day1=1; } else if(!isLeapYear(year1)&&month1==2&&day1==28) { month1=3; day1=1; } else day1=day1+1; } DateUtil r = new DateUtil(year1,month1,day1); return r; } public DateUtil getPreviousNDays(int n){//取得year-month-day的前n天日期 int year1=year,month1=month,day1=day; for(;n>0;n--) { while(n>366) { if(isLeapYear(year1)) n=n-366; else n=n-365; year1=year1-1; } if(month1==1&&day1==1) { year1=year1-1; month1=12; day1=31; } else if((month1==2||month1==4||month1==6||month1==8||month1==9||month1==11)&&day1==1) { month1=month1-1; day1=31; } else if((month1==5||month1==7||month1==10||month1==12)&&day1==1) { month1=month1-1; day1=30; } else if(isLeapYear(year1)&&month1==3&&day1==1) { month1=2; day1=29; } else if(!isLeapYear(year1)&&month1==3&&day1==1) { month1=2; day1=28; } else day1=day1-1; } DateUtil r = new DateUtil(year1,month1,day1); return r; } public boolean compareDates(DateUtil date){//比较当前日期与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.getDay()) return true; else if(day<date.getDay()) return false; else return false; } public boolean equalTwoDates(DateUtil date){//判断两个日期是否相等 if(year==date.getYear()&&month==date.getMonth()&&day==date.getDay()) return true; else return false; } public int getDaysofDates(DateUtil date){//求当前日期与date之间相差的天数 int num1=0,num2=0; DateUtil r = new DateUtil(year,month,day); for(r.month=r.month-1;r.month>0;r.month--) { if(r.month==1||r.month==3||r.month==5||r.month==7||r.month==8||r.month==10||r.month==12) num1=num1+31; if(r.month==4||r.month==6||r.month==9||r.month==11) num1=num1+30; if(isLeapYear(r.year)&&r.month==2) num1=num1+29; else if(r.month==2) num1=num1+28; } for(r.year=r.year-1;r.year>1800;r.year--) { if(isLeapYear(r.year)) num1=num1+366; else num1=num1+365; } num1=num1+r.day; for(date.month=date.month-1;date.month>0;date.month--) { if(date.month==1||date.month==3||date.month==5||date.month==7||date.month==8||date.month==10||date.month==12) num2=num2+31; if(date.month==4||date.month==6||date.month==9||date.month==11) num2=num2+30; if(isLeapYear(date.year)&&date.month==2) num2=num2+29; else if(date.month==2) num2=num2+28; } for(date.year=date.year-1;date.year>1800;date.year--) { if(isLeapYear(date.year)) num2=num2+366; else num2=num2+365; } num2=num2+date.day; if(num1>num2) return num1-num2; else if (num1<num2) return num2-num1; else return 1; } public String showDate(){//以“year-month-day”格式返回日期值 String t =""+year+'-'+month+'-'+day; return t; } }
4.题目集3 7-3(日期问题面向对象设计(聚合一))有些难度
先根据所给类图码出图中的类,再利用码出的类去完成题目的需求。和前一题相似,需要熟悉类与类之间的关系

应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用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且输入均有效,输出格式如下:
year-month-day - 当第一个数字为2且输入均有效,输出格式如下:
year-month-day - 当第一个数字为3且输入均有效,输出格式如下:
天数值
踩坑心得:因为类中的变量都是private所以不能直接访问,需要使用get方法 如获取年份:day.getMonth().getyear().getvalue()。
以及类Day中mon_maxnum[ ]中2月最大是28,所以闰年2月需要另外判断。然后带参数的构造方法应该使用set()的方法详细看代码
有些DateUtil类中的方法返回的是DateUtil类的变量,所以返回前需要先构造一个新的DateUtil类的变量再返回。
所给的日期范围和之前的不一样,需要更改范围;返回字符串:String t =""+year+'-'+month+'-'+day;
代码如下:
1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 // TODO 自动生成的方法存根 7 Scanner input = new Scanner(System.in); 8 int year = 0; 9 int month = 0; 10 int day = 0; 11 12 int choice = input.nextInt(); 13 14 if (choice == 1) { // test getNextNDays method 15 int m = 0; 16 year = Integer.parseInt(input.next()); 17 month = Integer.parseInt(input.next()); 18 day = Integer.parseInt(input.next()); 19 20 DateUtil date = new DateUtil(day, month, year); 21 22 if (!date.checkInputValidity()) { 23 System.out.println("Wrong Format"); 24 System.exit(0); 25 } 26 27 m = input.nextInt(); 28 29 if (m < 0) { 30 System.out.println("Wrong Format"); 31 System.exit(0); 32 } 33 34 System.out.println(date.getNextNDays(m).showDate()); 35 } else if (choice == 2) { // test getPreviousNDays method 36 int n = 0; 37 year = Integer.parseInt(input.next()); 38 month = Integer.parseInt(input.next()); 39 day = Integer.parseInt(input.next()); 40 41 DateUtil date = new DateUtil(day, month, year); 42 43 if (!date.checkInputValidity()) { 44 System.out.println("Wrong Format"); 45 System.exit(0); 46 } 47 48 n = input.nextInt(); 49 50 if (n < 0) { 51 System.out.println("Wrong Format"); 52 System.exit(0); 53 } 54 55 System.out.println(date.getPreviousNDays(n).showDate()); 56 } else if (choice == 3) { //test getDaysofDates method 57 year = Integer.parseInt(input.next()); 58 month = Integer.parseInt(input.next()); 59 day = Integer.parseInt(input.next()); 60 61 int anotherYear = Integer.parseInt(input.next()); 62 int anotherMonth = Integer.parseInt(input.next()); 63 int anotherDay = Integer.parseInt(input.next()); 64 65 DateUtil fromDate = new DateUtil(day, month, year); 66 DateUtil toDate = new DateUtil(anotherDay,anotherMonth,anotherYear); 67 68 if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { 69 System.out.println(fromDate.getDaysofDates(toDate)); 70 } else { 71 System.out.println("Wrong Format"); 72 System.exit(0); 73 } 74 } 75 else{ 76 System.out.println("Wrong Format"); 77 System.exit(0); 78 } 79 80 } 81 82 } 83 84 class Year{ 85 private int value; 86 87 public Year() { 88 super(); 89 // TODO 自动生成的构造函数存根 90 } 91 92 public Year(int value) { 93 super(); 94 this.value = value; 95 } 96 97 public int getValue() { 98 return value; 99 } 100 101 public void setValue(int value) { 102 this.value = value; 103 } 104 105 public boolean isLeapYear(){//判断year是否为闰年 106 if((value%4==0&&value%100!=0)||value%400==0) return true; 107 else return false; 108 } 109 110 public boolean validate(){ 111 if(value>2050||value<1900) return false; 112 else return true; 113 } 114 115 public void YearIncrement() { 116 value++; 117 118 } 119 120 public void YearRrduction() { 121 value--; 122 } 123 } 124 125 class Month{ 126 private int value; 127 private Year year = new Year(); 128 129 public Month() { 130 super(); 131 // TODO 自动生成的构造函数存根 132 } 133 134 public Month(int yearValue, int monthValue) { 135 super(); 136 this.value = monthValue; 137 year.setValue(yearValue); 138 } 139 140 public int getValue() { 141 return value; 142 } 143 144 public void setValue(int value) { 145 this.value = value; 146 } 147 148 public Year getYear() { 149 return year; 150 } 151 152 public void setYear(Year year) { 153 this.year = year; 154 } 155 156 public void resetMin() { 157 value=1; 158 } 159 160 public void resetMax() { 161 value=12; 162 } 163 164 public boolean validate() { 165 if(value>=1&&value<=12) return true; 166 else return false; 167 } 168 169 public void monthIncrement() { 170 if(value<12) value++; 171 } 172 173 public void monthReduction() { 174 if(value>1) value--; 175 } 176 } 177 178 class Day{ 179 private int value; 180 private Month month = new Month(); 181 private int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31}; 182 public Day() { 183 super(); 184 // TODO 自动生成的构造函数存根 185 } 186 public Day(int value, Month month, int[] mon_maxnum) { 187 super(); 188 this.value = value; 189 this.month = month; 190 this.mon_maxnum = mon_maxnum; 191 } 192 public int getValue() { 193 return value; 194 } 195 public void setValue(int value) { 196 this.value = value; 197 } 198 public Month getMonth() { 199 return month; 200 } 201 public void setMonth(Month value) { 202 this.month = value; 203 } 204 public void reseMin(){ 205 value=1; 206 } 207 public void reseMax(){ 208 value=mon_maxnum[month.getValue()]; 209 } 210 public boolean vaildate() { 211 if(value>=1&&value<=mon_maxnum[month.getValue()-1]) return true; 212 else return false; 213 } 214 public void dayIcrement() { 215 if(value<mon_maxnum[month.getValue()]) value++; 216 } 217 public void dayReduction() { 218 if(value>1) value--; 219 } 220 } 221 class DateUtil{ 222 private Day day = new Day(); 223 224 public DateUtil() { 225 super(); 226 // TODO 自动生成的构造函数存根 227 } 228 229 public DateUtil(int d, int m, int y) { 230 super(); 231 232 day.setValue(d); 233 day.getMonth().setValue(m); 234 day.getMonth().getYear().setValue(y); 235 } 236 237 public Day getDay() { 238 return day; 239 } 240 241 public void setDay(Day day) { 242 this.day = day; 243 } 244 245 public boolean checkInputValidity(){//检测输入的年、月、日是否合法 246 if(day.getMonth().validate()&&day.getMonth().getYear().validate()&&day.getValue()>=1) { 247 if(day.vaildate()) 248 return true; 249 else return false; 250 } 251 else return false; 252 } 253 public boolean isLeapYear(int year){//判断year是否为闰年 254 if((year%4==0&&year%100!=0)||year%400==0) return true; 255 else return false; 256 } 257 258 public boolean compareDates(DateUtil date){//比较当前日期与date的大小(先后) 259 if(day.getMonth().getYear().getValue()>date.getDay().getMonth().getYear().getValue()) return true; 260 else if(day.getMonth().getYear().getValue()<date.getDay().getMonth().getYear().getValue()) return false; 261 else if(day.getMonth().getValue()>date.getDay().getMonth().getValue())return true; 262 else if(day.getMonth().getValue()<date.getDay().getMonth().getValue())return false; 263 else if(day.getValue()>date.getDay().getValue()) return true; 264 else return false; 265 } 266 267 public boolean equalTwoDates(DateUtil date){//判断两个日期是否相等 268 if(day.getValue()==date.getDay().getValue()&&day.getMonth().getValue()==date.getDay().getMonth().getValue()&&day.getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue()) return true; 269 else return false; 270 } 271 272 public String showDate(){//以“year-month-day”格式返回日期值 273 String t =""+day.getMonth().getYear().getValue()+'-'+day.getMonth().getValue()+'-'+day.getValue(); 274 return t; 275 } 276 public DateUtil getNextNDays(int n){//取得year-month-day的下n天日期 277 int year1=day.getMonth().getYear().getValue(),month1=day.getMonth().getValue(),day1=day.getValue(); 278 for(;n>0;n--) { 279 while(n>366) { 280 if(isLeapYear(year1)) n=n-366; 281 else n=n-365; 282 283 year1=year1+1; 284 } 285 286 if(month1==12&&day1==31) { 287 year1=year1+1; 288 month1=1; 289 day1=1; 290 } 291 else if((month1==1||month1==3||month1==5||month1==7||month1==8||month1==10)&&day1==31) { 292 month1=month1+1; 293 day1=1; 294 } 295 else if((month1==4||month1==6||month1==9||month1==11)&&day1==30) { 296 month1=month1+1; 297 day1=1; 298 } 299 else if(isLeapYear(year1)&&month1==2&&day1==29) { 300 month1=3; 301 day1=1; 302 } 303 else if(!isLeapYear(year1)&&month1==2&&day1==28) { 304 month1=3; 305 day1=1; 306 } 307 else day1=day1+1; 308 } 309 DateUtil r = new DateUtil(day1,month1,year1); 310 return r; 311 } 312 313 public DateUtil getPreviousNDays(int n){//取得year-month-day的前n天日期 314 int year1=day.getMonth().getYear().getValue(),month1=day.getMonth().getValue(),day1=day.getValue(); 315 316 for(;n>0;n--) { 317 318 while(n>366) { 319 if(isLeapYear(year1)) n=n-366; 320 else n=n-365; 321 322 year1=year1-1; 323 } 324 325 if(month1==1&&day1==1) { 326 year1=year1-1; 327 month1=12; 328 day1=31; 329 } 330 else if((month1==2||month1==4||month1==6||month1==8||month1==9||month1==11)&&day1==1) { 331 month1=month1-1; 332 day1=31; 333 } 334 else if((month1==5||month1==7||month1==10||month1==12)&&day1==1) { 335 month1=month1-1; 336 day1=30; 337 } 338 else if(isLeapYear(year1)&&month1==3&&day1==1) { 339 month1=2; 340 day1=29; 341 } 342 else if(!isLeapYear(year1)&&month1==3&&day1==1) { 343 month1=2; 344 day1=28; 345 } 346 else day1=day1-1; 347 } 348 DateUtil r = new DateUtil(day1,month1,year1); 349 return r; 350 } 351 352 353 public int getDaysofDates(DateUtil date){//求当前日期与date之间相差的天数 354 int num1=0,num2=0,month1,month2,year1,year2; 355 month1=day.getMonth().getValue(); 356 year1=day.getMonth().getYear().getValue(); 357 358 month2=date.getDay().getMonth().getValue(); 359 year2=date.getDay().getMonth().getYear().getValue(); 360 361 for(month1=month1-1;month1>0;month1--) { 362 if(month1==1||month1==3||month1==5||month1==7||month1==8||month1==10||month1==12) num1=num1+31; 363 if(month1==4||month1==6||month1==9||month1==11) num1=num1+30; 364 if(isLeapYear(year1)&&month1==2) num1=num1+29; 365 else if(month1==2) num1=num1+28; 366 } 367 for(year1=year1-1;year1>1800;year1--) { 368 if(isLeapYear(year1)) num1=num1+366; 369 else num1=num1+365; 370 } 371 num1=num1+day.getValue(); 372 373 for(month2=month2-1;month2>0;month2--) { 374 if(month2==1||month2==3||month2==5||month2==7||month2==8||month2==10||month2==12) num2=num2+31; 375 if(month2==4||month2==6||month2==9||month2==11) num2=num2+30; 376 if(isLeapYear(year2)&&month2==2) num2=num2+29; 377 else if(month2==2) num2=num2+28; 378 } 379 for(year2=year2-1;year2>1800;year2--) { 380 if(isLeapYear(year2)) num2=num2+366; 381 else num2=num2+365; 382 } 383 num2=num2+date.getDay().getValue(); 384 385 if(num1>num2) return num1-num2; 386 else if (num1<num2) return num2-num1; 387 else return 0; 388 } 389 }
5.题目集3 7-4 日期问题面向对象设计(聚合二)
参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用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:值
踩坑心得:注意这题的类之间的关系和上题的类之间的关系不一样,要根据所给图在的关系写,获取数据的方法和上题也不一样。
有些DateUtil类中的方法返回的是DateUtil类的变量,所以返回前需要先构造一个新的DateUtil类的变量再返回。
返回字符串:String t =""+year+'-'+month+'-'+day;
代码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自动生成的方法存根 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().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " 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().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " 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 Year{ private int value; public Year() { super(); // TODO 自动生成的构造函数存根 } public Year(int value) { super(); this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public boolean isLeapYear(){//判断year是否为闰年 if((value%4==0&&value%100!=0)||value%400==0) return true; else return false; } public boolean validate(){ if(value>2020||value<1820) return false; else return true; } public void YearIncrement() { value++; } public void YearRrduction() { value--; } } class Month{ private int value; public Month() { super(); // TODO 自动生成的构造函数存根 } public Month(int monthValue) { super(); this.value = monthValue; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public void resetMin() { value=1; } public void resetMax() { value=12; } public boolean validate() { if(value>=1&&value<=12) return true; else return false; } public void monthIncrement() { if(value<12) value++; } public void monthReduction() { if(value>1) value--; } } class Day{ private int value; public Day() { super(); // TODO 自动生成的构造函数存根 } public Day(int value) { super(); this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public void dayIcrement() { if(value<31) value++; } public void dayReduction() { if(value>1) value--; } } class DateUtil{ private Day day = new Day(); private Month month = new Month(); private Year year = new Year(); private int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil(int y, int m, int d) { super(); day.setValue(d); month.setValue(m); year.setValue(y); ; } public DateUtil() { super(); // TODO 自动生成的构造函数存根 } public Day getDay() { return day; } public void setDay(Day day) { this.day = day; } public Month getMonth() { return month; } public void setMonth(Month month) { this.month = month; } public Year getYear() { return year; } public void setYear(Year year) { this.year = year; } public void setDayMin() { day.setValue(1); } public void setDayMax() { day.setValue(mon_maxnum[month.getValue()-1]); } public boolean checkInputValidity(){//检测输入的年、月、日是否合法 if(month.validate()&&year.validate()&&month.getValue()!=2) { if(day.getValue()>=1&&day.getValue()<=mon_maxnum[month.getValue()-1]) return true; else return false; } else if(month.getValue()==2) { if(day.getValue()>=1&&day.getValue()<=29) return true; else return false; } else return false; } public DateUtil getNextNDays(int n){//取得year-month-day的下n天日期 int year1=year.getValue(),month1=month.getValue(),day1=day.getValue(); for(;n>0;n--) { while(n>366) { if(isLeapYear(year1)) n=n-366; else n=n-365; year1=year1+1; } if(month1==12&&day1==31) { year1=year1+1; month1=1; day1=1; } else if((month1==1||month1==3||month1==5||month1==7||month1==8||month1==10)&&day1==31) { month1=month1+1; day1=1; } else if((month1==4||month1==6||month1==9||month1==11)&&day1==30) { month1=month1+1; day1=1; } else if(isLeapYear(year1)&&month1==2&&day1==29) { month1=3; day1=1; } else if(!isLeapYear(year1)&&month1==2&&day1==28) { month1=3; day1=1; } else day1=day1+1; } DateUtil r = new DateUtil(year1,month1,day1); return r; } public DateUtil getPreviousNDays(int n){//取得year-month-day的前n天日期 int year1=year.getValue(),month1=month.getValue(),day1=day.getValue(); for(;n>0;n--) { while(n>366) { if(isLeapYear(year1)) n=n-366; else n=n-365; year1=year1-1; } if(month1==1&&day1==1) { year1=year1-1; month1=12; day1=31; } else if((month1==2||month1==4||month1==6||month1==8||month1==9||month1==11)&&day1==1) { month1=month1-1; day1=31; } else if((month1==5||month1==7||month1==10||month1==12)&&day1==1) { month1=month1-1; day1=30; } else if(isLeapYear(year1)&&month1==3&&day1==1) { month1=2; day1=29; } else if(!isLeapYear(year1)&&month1==3&&day1==1) { month1=2; day1=28; } else day1=day1-1; } DateUtil r = new DateUtil(year1,month1,day1); return r; // for(;n>0;n--) { // while(n>366) { // if(isLeapYear(year1)) n=n-366; // else n=n-365; // // year1=year1-1; // } // if(n<=0) break; // if(month1==1&&day1==1) { // year1=year1-1; // month1=12; // day1=31; // } // else if((month1==2||month1==4||month1==6||month1==8||month1==9||month1==11)&&day1==1) { // month1=month1-1; // day1=31; // } // else if((month1==5||month1==7||month1==10||month1==12)&&day1==1) { // month1=month1-1; // day1=30; // } // else if(isLeapYear(year1)&&month1==3&&day1==1) { // month1=2; // day1=29; // } // else if(isLeapYear(year1)&&month1==3&&day1==1) { // month1=2; // day1=28; // } // else if(day1!=1) day1=day1-1; // } // DateUtil r = new DateUtil(year1,month1,day1); // return r; } public boolean compareDates(DateUtil date){//比较当前日期与date的大小(先后) if(year.getValue()>date.getYear().getValue()) return true; else if(year.getValue()<date.getYear().getValue()) return false; else if(month.getValue()>date.getMonth().getValue())return true; else if(month.getValue()<date.getMonth().getValue())return false; else if(day.getValue()>date.getDay().getValue()) return true; else return false; } public boolean equalTwoDates(DateUtil date){//判断两个日期是否相等 if(day.getValue()==date.getDay().getValue()&month.getValue()==date.getMonth().getValue()&&year.getValue()==date.getYear().getValue()) return true; else return false; } public int getDaysofDates(DateUtil date){//求当前日期与date之间相差的天数 int num1=0,num2=0,month1,month2,year1,year2; month1=month.getValue(); year1=year.getValue(); month2=date.getMonth().getValue(); year2=date.getYear().getValue(); for(month1=month1-1;month1>0;month1--) { if(month1==1||month1==3||month1==5||month1==7||month1==8||month1==10||month1==12) num1=num1+31; if(month1==4||month1==6||month1==9||month1==11) num1=num1+30; if(isLeapYear(year1)&&month1==2) num1=num1+29; else if(month1==2) num1=num1+28; } for(year1=year1-1;year1>1800;year1--) { if(isLeapYear(year1)) num1=num1+366; else num1=num1+365; } num1=num1+day.getValue(); for(month2=month2-1;month2>0;month2--) { if(month2==1||month2==3||month2==5||month2==7||month2==8||month2==10||month2==12) num2=num2+31; if(month2==4||month2==6||month2==9||month2==11) num2=num2+30; if(isLeapYear(year2)&&month2==2) num2=num2+29; else if(month2==2) num2=num2+28; } for(year2=year2-1;year2>1800;year2--) { if(isLeapYear(year2)) num2=num2+366; else num2=num2+365; } num2=num2+date.getDay().getValue(); if(num1>num2) return num1-num2; else if (num1<num2) return num2-num1; else return 0; } public String showDate(){//以“year-month-day”格式返回日期值 String t =""+year.getValue()+'-'+month.getValue()+'-'+day.getValue(); return t; } public boolean isLeapYear(int year){//判断year是否为闰年 if((year%4==0&&year%100!=0)||year%400==0) return true; else return false; } }
(3)踩坑心得:.next()不可以接收空格,.nextLine()可以接收空格。需要先把数据前的空闲位1跳过,然后找到起始位0,之后的8位为有效数据,再之后的两个位是奇偶校验位和结束位,
结束位一定为1不然直接输出“validate error”,奇偶校验位采用奇校验,就是8位有效数据加奇偶校验位的和为奇数才是正确的。还需要先判断起始位后是否有11位数据。
单个字符要用单引号‘ ’ 如:‘a'. 需要先判断输入的字符是否在a~z 或 A~Z 之间。设计一个类中的方法 传入一个字符可返回相应的数字。
特别注意闰年会多一天,比较两个日期的大小时可用这两个日期到同一天(如 1800 1 1)的天数相减。判断是否为闰年(year%4==0&&year%100!=0)||year%400==0),,
闰年求前n天和后n天时需要判断是否在2月29号前后。判断下n天和前n天要注意有多种情况:年的+-1, 月的+-1,闰年二月29的+-1.
因为类中的变量都是private所以不能直接访问,需要使用get方法 如获取年份:day.getMonth().getyear().getvalue()。
以及类Day中mon_maxnum[ ]中2月最大是28,所以闰年2月需要另外判断。然后带参数的构造方法应该使用set()的方法详细看代码
有些DateUtil类中的方法返回的是DateUtil类的变量,所以返回前需要先构造一个新的DateUtil类的变量再返回。
所给的日期范围和之前的不一样,需要更改范围;返回字符串:String t =""+year+'-'+month+'-'+day;
注意这题的类之间的关系和上题的类之间的关系不一样,要根据所给图在的关系写,获取数据的方法和上题也不一样。
有些DateUtil类中的方法返回的是DateUtil类的变量,所以返回前需要先构造一个新的DateUtil类的变量再返回。
返回字符串:String t =""+year+'-'+month+'-'+day;
double类相加减有误差,
(4)改进建议:
可以多放几个测试点。
(5)总结:
- 做题前先认真看题,需要读懂题目意思和题目的输出格式要求。
- 学习到了方法和类的使用,看类图和一些String类的常用方法比如Sting转化为double。
- 理清类与类之间的关系使用起来会快很多。
- Java所给的方法需要进一步学习及研究,加强面向对象的思维。
浙公网安备 33010602011771号