第二次博客作业
第二次博客作业
一、前言:
第四次题目集知识点涉及:
正则表达式、字符串合法性校验、类的封装与设计、类的无参构造、类的有参构造、类的继承、重写父类。此次题目及需要完成的内容和功能较多,比较复杂,第一题难度偏大。
第五次题目集知识点涉及:
类的设计与封装、类的无参构造、类的有参构造、正则表达式、排序算法(冒泡排序、插入排序、选择排序)。此次题目一共有四题,其中第二道需要用到正则表达式来判断关键字的出现次数,需要掌握正则表达式的使用。
第六次题目集知识点涉及:
正则表达式、排序算法、类的封装与设计、类的继承、类的无参构造、类的有参构造、类的多态。其中前四题主要是对正则表达式的考察,难度并不大。后两题需要设计的内容较多,难度适中。
二、设计与分析:
①题目集4(7-2)、题目集5(7-4)两种日期类聚合设计:
7-2
7-4
通过类图可以看到,两种日期类聚合的设计最明显的区别在于虽然类的名称和类型相同,但是类中的方法有很多不同。虽然两种设计中的方法都相同,但是方法所属的类不同。最明显的区别就在于DateUtil类和Day类的不同,7-2中的month相关方法、日期复位、日期最大值、校验数据合法性等方法在7-4中全部移到了DateUtil类当中,实现的功能相同。
日期聚合一的优点在于类与类之间的联系紧密,关系密切,调用时方便。缺点在于代码的可维护性不高,当功能需要调整时必须对代码进行大量的修改。
日期聚合二的优点在于各个模块的功能界限十分清晰,各个类之间没有重合的部分,需要实现的功能都封装在各自的类中。但是初期代码的编写比较复杂,需要事先进行足够的设计。
7-2源码如下:
import java.util.Scanner;
class Day{
int value;
Month month;
int mon_maxnum[] = {31,28,31,30,31,30,31,31,30,31,30,31};
Day(){
//默认构造方法
}
Day(int yearValue, int monthValue, int dayValue){
//带参构造方法
this.month = new Month(yearValue, monthValue);
this.value = dayValue;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Month getMonth() {
return month;
}
public void setMonth(Month value) {
this.month = value;
}
public void resetMin() {
//日期复位(1)
value = 1;
}
public void resetMax() {
//日期设为该月最大值
value = mon_maxnum[month.getValue()-1];
}
public boolean validate() {
//校验数据合法性
if(this.getMonth().getYear().isLeapYear())
mon_maxnum[1]=29;
if(value>=1&&value<=mon_maxnum[month.getValue()-1])
return true;
else
return false;
}
public void dayIncrement() {
//日期增1
value++;
}
public void dayReduction() {
//日期减1
value--;
}
}
class Month{
int value;
Year year;
Month(){
}
Month(int yearValue,int monthValue){
this.year = new Year(yearValue);
this.value = monthValue;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Year getYear() {
return year;
}
public void setYear(Year year) {
this.year = year;
}
public void resetMin() {
//月份复位1
value = 1;
}
public void resetMax() {
//月份设置为12
value = 12;
}
public boolean validate() {
//校验数据合法性
if(value>=1&&value<=12)
return true;
else
return false;
}
public void monthIncrement() {
//月份增1
value++;
}
public void monthReduction() {
//月份减1
value--;
}
}
class Year{
int value;
Year(){
}
Year(int value){
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isLeapYear() {
//判断是否为闰年
if((value%4==0&&value%100!=0)||value%400==0)
return true;
else
return false;
}
public boolean validate() {
//校验数据合法性
if(value<=2050&&value>=1900)
return true;
else
return false;
}
public void yearIncrement() {
//年份增1
value++;
}
public void yearReduction() {
//年份减一
value--;
}
}//class Year
class DateUtil {
Day day;
DateUtil(){
}
DateUtil(int d, int m, int y){
this.day=new Day(d,m,y);
}
public Day getDay() {
//day setter
return day;
}
public void setDay(Day d) {
this.day = d;
}
public boolean checkInputValidity() {
//校验数据合法性
if(this.getDay().getMonth().getYear().validate()&&this.getDay().getMonth().validate()&&day.validate())//检验年月日
return true;
else
return false;
}
public boolean compareDates(DateUtil date) {
//比较两个日期的大小
if(date.getDay().getMonth().getYear().getValue()<this.getDay().getMonth().getYear().getValue())//比较年
return false;
else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()<this.getDay().getMonth().getValue())//年相等,月后者月更大
return false;
else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()==this.getDay().getMonth().getValue()&&date.getDay().getValue()<this.getDay().getValue())
return false;
else
return true;
//传入的日期和这个类中的日期比较,如果类的日期大,返回false
}
public boolean equalTwoDates(DateUtil date) {
//判定两个日期是否相等
if(this.getDay().getValue()==date.getDay().getValue()&&this.getDay().getMonth().getValue()==date.getDay().getMonth().getValue()&& this.getDay().getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue())
return true;
else
return false;
}
public String showDate() {
//日期格式化
return this.getDay().getMonth().getYear().getValue()+"-"+this.getDay().getMonth().getValue()+"-"+this.getDay().getValue();
}
public int syts(DateUtil d){
//计算该年的剩余天数
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int b=0;
int i;
for(i=d.getDay().getMonth().getValue()+1;i<=12;i++){
b=b+a[i];
}
b=b+a[d.getDay().getMonth().getValue()]-d.getDay().getValue();
if(d.getDay().getMonth().getYear().isLeapYear()&&d.getDay().getMonth().getValue()<=2)//闰年
b++;
return b;
}
public DateUtil getNextNDays(int n) {
//求下n天
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int y=0,m=0,d=0;
int i,j;
int b=syts(this);//该年剩余天数
if(b>n){//该年剩余天数大于n
y=this.getDay().getMonth().getYear().getValue();
if(this.getDay().getMonth().getYear().isLeapYear()){//如果是闰年
a[2]=29;
}
int e=a[this.getDay().getMonth().getValue()];//该月的天数
e=e-this.getDay().getValue();//本月剩余的天数
if(e>=n){//如果n天后在本月
m=this.getDay().getMonth().getValue();
d=n+this.getDay().getValue();
}
else{//如果n天后不在本月
n=n-e;
m=this.getDay().getMonth().getValue()+1;
i=m;
while(n-a[i]>0&&i<=12){//找到月
n=n-a[i];
m++;
i++;
}
d=n;//找到天
}
}
else{//该年剩余天数小于n
n=n-b;
y=this.getDay().getMonth().getYear().getValue()+1;
int c=365;//平年天数
if(new Year(y).isLeapYear()){//闰年天数
c++;
}
while(n-c>0){//找到年
n=n-c;
y++;
c=365;
if(new Year(y).isLeapYear())
c++;
}
i=1;
while(n-a[i]>0&&i<=12){//找到月
n=n-a[i];
i++;
}
m=i;
d=n;//找到天
}
return new DateUtil(y, m, d);
}
public DateUtil getPreviousNDays(int n) {
//求前n天
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int y=0,m=0,d=0;
int i,b;
b=365-syts(this);//该日期所在年份已经过的天数
if(this.getDay().getMonth().getYear().isLeapYear()){//如果是闰年
b++;
}
if (b>n){//如果前n天在该年
y=this.getDay().getMonth().getYear().getValue();
int e=this.getDay().getValue();//本月已经过的天数
if(e>n){//如果前n天在本月
m=this.getDay().getMonth().getValue();
d=e-n;
}
else{//如果前n天不在本月
n=n-e;
m=this.getDay().getMonth().getValue()-1;
i=m;
while(n-a[i]>0&&i>=0){//找到月
n=n-a[i];
m--;
i--;
}
d=a[i]-n;//找到天
if(new Year(y).isLeapYear()&&m==2){
d++;
}
}
}
else{//如果前n天不在该年
n=n-b;
y=this.getDay().getMonth().getYear().getValue()-1;
int f=365;
if(new Year(y).isLeapYear()){
f++;
}
while(n-f>0){//找到年
n=n-f;
y--;
f=365;
if(new Year(y).isLeapYear())
f++;
}
i=12;
while(n-a[i]>0&&i>=0){//找到月
n=n-a[i];
i--;
}
m=i;
d=a[i]-n;//找到天
if(new Year(f).isLeapYear()&&m==2){
d++;
}
}
return new DateUtil(y, m, d);
}
public int getDaysofDates(DateUtil date) {
//求两个日期之间的天数
DateUtil b1=this;
DateUtil b2=date;
if(this.equalTwoDates(date)){//如果两天的日期相等
return 0;
}
else if(!this.compareDates(date)){//如果日期大小不对
b1=date;
b2=this;
}
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int i,j,ts=0;
for(i=b1.getDay().getMonth().getYear().getValue()+1;i<b2.getDay().getMonth().getYear().getValue();i++){//两个日期的年数之和
ts=ts+365;
if(new Year(i).isLeapYear())
ts++;
}
if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()==b2.getDay().getMonth().getValue()){//年份相同,月份相同,日不同
ts=b2.getDay().getValue()-b1.getDay().getValue();
}
else if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()!=b2.getDay().getMonth().getValue()){//年份相同,月份不同
if(b1.getDay().getMonth().getYear().isLeapYear())//是闰年
a[2]=29;
ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期该月剩余的天数
ts=ts+b2.getDay().getValue();//大日期的天数
for(j=b1.getDay().getMonth().getValue()+1;j<=b2.getDay().getMonth().getValue()-1;j++)//月份天数和
ts+=a[j];
}
else if(b1.getDay().getMonth().getYear().getValue()!=b2.getDay().getMonth().getYear().getValue()){//年份不同
ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期在该月剩余的天数
ts=ts+b2.getDay().getValue();//大日期在该月已经过的天数
for(j=b1.getDay().getMonth().getValue()+1;j<=12;j++)//小日期在该年剩余的天数
ts=ts+a[j];
for(j=b2.getDay().getMonth().getValue()-1;j>0;j--)//大日期在该年已经过的天数
ts=ts+a[j];
if(b1.getDay().getMonth().getYear().isLeapYear()&&b1.getDay().getMonth().getValue()<=2)//如果小日期该年为闰年且该天在1月或2月
ts++;
if(b2.getDay().getMonth().getYear().isLeapYear()&&b2.getDay().getMonth().getValue()>2)//如果大日期该年为闰年且该天在1月或2月后
ts++;
}
return ts;
}
}//class DateUtil
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner x=new Scanner(System.in);
int year=0,month=0,day=0,a,b;
a=x.nextInt();//输入判断类型
year=x.nextInt();month= x.nextInt();day=x.nextInt();//输入年月日
DateUtil c=new DateUtil(year,month,day);
if(a==1){//求下n天
b=x.nextInt();//输入n
if(!c.checkInputValidity()||b<0){//如果数据不合法
System.out.println("Wrong Format");
System.exit(0);
}
else
System.out.println(c.getNextNDays(b).showDate());
}
else if(a==2){
b=x.nextInt();//输入n
if(!c.checkInputValidity()||b<0){//如果数据不合法
System.out.println("Wrong Format");
System.exit(0);
}
else
System.out.println(c.getPreviousNDays(b).showDate());
}
else if(a==3){
int y1,m1,d1;
y1=x.nextInt();m1= x.nextInt();d1=x.nextInt();//输入第二个年月日
DateUtil d=new DateUtil(y1,m1,d1);
if(!c.checkInputValidity()||!d.checkInputValidity()){//如果数据不合法
System.out.println("Wrong Format");
System.exit(0);
}
else
System.out.println(c.getDaysofDates(d));
}
else
System.out.println("Wrong Format");
}
}
7-4源码如下:
import java.util.*;
class Getmeaningless1{
public int Get0() {
int a = 1;
int b = 2;
int c = 3;
c = a*2-b;
return c;
}
public int Get1() {
int a = 2;
int b = 4;
int c = 3;
c = a*2-b+1;
return c;
}
public int Get2() {
int a = 2;
int b = 4;
int c = 3;
c = b-a;
return c;
}
public int Get3() {
int a = 7;
int b = 4;
int c = 3;
c = a-b;
return c;
}
public int Get4() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+1;
return c;
}
public int Get5() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+2;
return c;
}
}
class Getmeaningless2{
public int Get0() {
int a = 1;
int b = 2;
int c = 3;
c = a*2-b;
return c;
}
public int Get1() {
int a = 2;
int b = 4;
int c = 3;
c = a*2-b+1;
return c;
}
public int Get2() {
int a = 2;
int b = 4;
int c = 3;
c = b-a;
return c;
}
public int Get3() {
int a = 7;
int b = 4;
int c = 3;
c = a-b;
return c;
}
public int Get4() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+1;
return c;
}
public int Get5() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+2;
return c;
}
}
class Getmeaningless3{
public int Get0() {
int a = 1;
int b = 2;
int c = 3;
c = a*2-b;
return c;
}
public int Get1() {
int a = 2;
int b = 4;
int c = 3;
c = a*2-b+1;
return c;
}
public int Get2() {
int a = 2;
int b = 4;
int c = 3;
c = b-a;
return c;
}
public int Get3() {
int a = 7;
int b = 4;
int c = 3;
c = a-b;
return c;
}
public int Get4() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+1;
return c;
}
public int Get5() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+2;
return c;
}
}
class Getmeaningless4{
public int Get0() {
int a = 1;
int b = 2;
int c = 3;
c = a*2-b;
return c;
}
public int Get1() {
int a = 2;
int b = 4;
int c = 3;
c = a*2-b+1;
return c;
}
public int Get2() {
int a = 2;
int b = 4;
int c = 3;
c = b-a;
return c;
}
public int Get3() {
int a = 7;
int b = 4;
int c = 3;
c = a-b;
return c;
}
public int Get4() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+1;
return c;
}
public int Get5() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+2;
return c;
}
}
class Getmeaningless5{
public int Get0() {
int a = 1;
int b = 2;
int c = 3;
c = a*2-b;
return c;
}
public int Get1() {
int a = 2;
int b = 4;
int c = 3;
c = a*2-b+1;
return c;
}
public int Get2() {
int a = 2;
int b = 4;
int c = 3;
c = b-a;
return c;
}
public int Get3() {
int a = 7;
int b = 4;
int c = 3;
c = a-b;
return c;
}
public int Get4() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+1;
return c;
}
public int Get5() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+2;
return c;
}
}
class Day{
int value;
Month month;
Getmeaningless1 Get1 = new Getmeaningless1();
Getmeaningless2 Get2 = new Getmeaningless2();
Getmeaningless3 Get3 = new Getmeaningless3();
Getmeaningless4 Get4 = new Getmeaningless4();
Getmeaningless5 Get5 = new Getmeaningless5();
int mon_maxnum[] = {Get1.Get1()*31,28,31,30,31,Get2.Get2()*15,31,31,Get3.Get2()*15,31,30,31};
Day(){
//默认构造方法
}
Day(int yearValue, int monthValue, int dayValue){
//带参构造方法
this.month = new Month(yearValue, monthValue);
this.value = dayValue;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Month getMonth() {
return month;
}
public void setMonth(Month value) {
this.month = value;
}
public void resetMin() {
//日期复位(1)
value = 1;
}
public void resetMax() {
//日期设为该月最大值
value = mon_maxnum[month.getValue()-1];
}
public boolean validate() {
//校验数据合法性
if(this.getMonth().getYear().isLeapYear())
mon_maxnum[1]=29;
if(value>=1&&value<=mon_maxnum[month.getValue()-1])
return true;
else
return false;
}
public void dayIncrement() {
//日期增1
value++;
}
public void dayReduction() {
//日期减1
value--;
}
}
class Month{
int value;
Year year;
Getmeaningless1 Get1 = new Getmeaningless1();
Getmeaningless2 Get2 = new Getmeaningless2();
Getmeaningless3 Get3 = new Getmeaningless3();
Getmeaningless4 Get4 = new Getmeaningless4();
Getmeaningless5 Get5 = new Getmeaningless5();
Month(){
}
Month(int yearValue,int monthValue){
this.year = new Year(yearValue);
this.value = monthValue;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Year getYear() {
return year;
}
public void setYear(Year year) {
this.year = year;
}
public void resetMin() {
//月份复位1
value = Get3.Get3()-2;
}
public void resetMax() {
//月份设置为12
value = Get5.Get4()*3;
}
public boolean validate() {
//校验数据合法性
if(value>=Get1.Get1()&&value<=Get3.Get3()*4)
return true;
else
return false;
}
public void monthIncrement() {
//月份增1
value = value+Get5.Get5()-4;
}
public void monthReduction() {
//月份减1
value = value+Get2.Get5()-6;
}
}
class Year{
int value;
Getmeaningless1 Get1 = new Getmeaningless1();
Getmeaningless2 Get2 = new Getmeaningless2();
Getmeaningless3 Get3 = new Getmeaningless3();
Getmeaningless4 Get4 = new Getmeaningless4();
Getmeaningless5 Get5 = new Getmeaningless5();
Year(){
}
Year(int value){
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isLeapYear() {
//判断是否为闰年
if((value%4==0&&value%100!=0)||value%400==0)
return true;
else
return false;
}
public boolean validate() {
//校验数据合法性
if(value<=2020&&value>=1820)
return true;
else
return false;
}
public void yearIncrement() {
//年份增1
value = value+Get5.Get5()-4;
}
public void yearReduction() {
//年份减一
value = value+Get5.Get5()-6;
}
}//class Year
class DateUtil {
Day day;
Getmeaningless1 Get1 = new Getmeaningless1();
Getmeaningless2 Get2 = new Getmeaningless2();
Getmeaningless3 Get3 = new Getmeaningless3();
Getmeaningless4 Get4 = new Getmeaningless4();
Getmeaningless5 Get5 = new Getmeaningless5();
DateUtil(){
}
DateUtil(int d, int m, int y){
this.day=new Day(d,m,y);
}
public Day getDay() {
//day setter
return day;
}
public void setDay(Day d) {
this.day = d;
}
public boolean checkInputValidity() {
//校验数据合法性
if(this.getDay().getMonth().getYear().validate()&&this.getDay().getMonth().validate()&&day.validate())//检验年月日
return true;
else
return false;
}
public boolean compareDates(DateUtil date) {
//比较两个日期的大小
if(date.getDay().getMonth().getYear().getValue()<this.getDay().getMonth().getYear().getValue())//比较年
return false;
else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()<this.getDay().getMonth().getValue())//年相等,月后者月更大
return false;
else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()==this.getDay().getMonth().getValue()&&date.getDay().getValue()<this.getDay().getValue())
return false;
else
return true;
//传入的日期和这个类中的日期比较,如果类的日期大,返回false
}
public boolean equalTwoDates(DateUtil date) {
//判定两个日期是否相等
if(this.getDay().getValue()==date.getDay().getValue()&&this.getDay().getMonth().getValue()==date.getDay().getMonth().getValue()&& this.getDay().getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue())
return true;
else
return false;
}
public String showDate() {
//日期格式化
return this.getDay().getMonth().getYear().getValue()+"-"+this.getDay().getMonth().getValue()+"-"+this.getDay().getValue();
}
public int syts(DateUtil d){
//计算该年的剩余天数
int a[]={0,31,Get5.Get2()*14,31,30,31,Get1.Get2()*15,31,31,Get4.Get2()*15,31,30,31};
int b=0;
int i;
for(i=d.getDay().getMonth().getValue()+1;i<=Get2.Get3()*4;i++){
b=b+a[i];
}
b=b+a[d.getDay().getMonth().getValue()]-d.getDay().getValue();
if(d.getDay().getMonth().getYear().isLeapYear()&&d.getDay().getMonth().getValue()<=2)//闰年
b++;
return b;
}
public DateUtil getNextNDays(int n) {
//求下n天
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int y=Get4.Get0(),m=Get2.Get0(),d=Get3.Get0();
int i,j;
int b=syts(this);//该年剩余天数
if(b>n){//该年剩余天数大于n
y=this.getDay().getMonth().getYear().getValue();
if(this.getDay().getMonth().getYear().isLeapYear()){//如果是闰年
a[2]=29;
}
int e=a[this.getDay().getMonth().getValue()];//该月的天数
e=e-this.getDay().getValue();//本月剩余的天数
if(e>=n){//如果n天后在本月
m=this.getDay().getMonth().getValue();
d=n+this.getDay().getValue();
}
else{//如果n天后不在本月
n=n-e;
m=this.getDay().getMonth().getValue()+1;
i=m;
while(n-a[i]>0&&i<=12){//找到月
n=n-a[i];
m++;
i++;
}
d=n;//找到天
}
}
else{//该年剩余天数小于n
n=n-b;
y=this.getDay().getMonth().getYear().getValue()+1;
int c=365;//平年天数
if(new Year(y).isLeapYear()){//闰年天数
c++;
}
while(n-c>0){//找到年
n=n-c;
y++;
c=365;
if(new Year(y).isLeapYear())
c++;
}
i=1;
while(n-a[i]>0&&i<=12){//找到月
n=n-a[i];
i++;
}
m=i;
d=n;//找到天
}
return new DateUtil(y, m, d);
}
public DateUtil getPreviousNDays(int n) {
//求前n天
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int y=Get1.Get0(),m=Get3.Get2()-2,d=Get4.Get1()-1;
int i,b;
b=365-syts(this);//该日期所在年份已经过的天数
if(this.getDay().getMonth().getYear().isLeapYear()){//如果是闰年
b++;
}
if (b>n){//如果前n天在该年
y=this.getDay().getMonth().getYear().getValue();
int e=this.getDay().getValue();//本月已经过的天数
if(e>n){//如果前n天在本月
m=this.getDay().getMonth().getValue();
d=e-n;
}
else{//如果前n天不在本月
n=n-e;
m=this.getDay().getMonth().getValue()-1;
i=m;
while(n-a[i]>0&&i>=(Get3.Get3()-3)){//找到月
n=n-a[i];
m--;
i--;
}
d=a[i]-n;//找到天
if(new Year(y).isLeapYear()&&m==2){
d++;
}
}
}
else{//如果前n天不在该年
n=n-b;
y=this.getDay().getMonth().getYear().getValue()-1;
int f=Get3.Get1()*365;//365
if(new Year(y).isLeapYear()){
f++;
}
while(n-f>0){//找到年
n=n-f;
y--;
f=365;
if(new Year(y).isLeapYear())
f++;
}
i=12;
while(n-a[i]>0&&i>=0){//找到月
n=n-a[i];
i--;
}
m=i;
d=a[i]-n;//找到天
if(new Year(f).isLeapYear()&&m==2){
d++;
}
}
return new DateUtil(y, m, d);
}
public int getDaysofDates(DateUtil date) {
//求两个日期之间的天数
DateUtil b1=this;
DateUtil b2=date;
if(this.equalTwoDates(date)){//如果两天的日期相等
return 0;
}
else if(!this.compareDates(date)){//如果日期大小不对
b1=date;
b2=this;
}
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int i,j,ts=0;
for(i=b1.getDay().getMonth().getYear().getValue()+1;i<b2.getDay().getMonth().getYear().getValue();i++){//两个日期的年数之和
ts=ts+365;
if(new Year(i).isLeapYear())
ts++;
}
if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()==b2.getDay().getMonth().getValue()){//年份相同,月份相同,日不同
ts=b2.getDay().getValue()-b1.getDay().getValue();
}
else if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()!=b2.getDay().getMonth().getValue()){//年份相同,月份不同
if(b1.getDay().getMonth().getYear().isLeapYear())//是闰年
a[2]=29;
ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期该月剩余的天数
ts=ts+b2.getDay().getValue();//大日期的天数
for(j=b1.getDay().getMonth().getValue()+1;j<=b2.getDay().getMonth().getValue()-1;j++)//月份天数和
ts+=a[j];
}
else if(b1.getDay().getMonth().getYear().getValue()!=b2.getDay().getMonth().getYear().getValue()){//年份不同
ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期在该月剩余的天数
ts=ts+b2.getDay().getValue();//大日期在该月已经过的天数
for(j=b1.getDay().getMonth().getValue()+1;j<=12;j++)//小日期在该年剩余的天数
ts=ts+a[j];
for(j=b2.getDay().getMonth().getValue()-1;j>0;j--)//大日期在该年已经过的天数
ts=ts+a[j];
if(b1.getDay().getMonth().getYear().isLeapYear()&&b1.getDay().getMonth().getValue()<=2)//如果小日期该年为闰年且该天在1月或2月
ts++;
if(b2.getDay().getMonth().getYear().isLeapYear()&&b2.getDay().getMonth().getValue()>2)//如果大日期该年为闰年且该天在1月或2月后
ts++;
}
return ts;
}
}//class DateUtil
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner x=new Scanner(System.in);
int year=0,month=0,day=0,a,b;
a=x.nextInt();//输入判断类型
year=x.nextInt();month= x.nextInt();day=x.nextInt();//输入年月日
DateUtil c=new DateUtil(year,month,day);
if(a==1){//求下n天
b=x.nextInt();//输入n
if(!c.checkInputValidity()||b<0){//如果数据不合法
System.out.println("Wrong Format");
System.exit(0);
}
else
System.out.println(year+"-"+month+"-"+day+" next "+b+" days is:"+c.getNextNDays(b).showDate());
}
else if(a==2){
b=x.nextInt();//输入n
if(!c.checkInputValidity()||b<0){//如果数据不合法
System.out.println("Wrong Format");
System.exit(0);
}
else
System.out.println(year+"-"+month+"-"+day+" previous "+b+" days is:" + c.getPreviousNDays(b).showDate());
}
else if(a==3){
int y1,m1,d1;
y1=x.nextInt();m1= x.nextInt();d1=x.nextInt();//输入第二个年月日
DateUtil d=new DateUtil(y1,m1,d1);
if(!c.checkInputValidity()||!d.checkInputValidity()){//如果数据不合法
System.out.println("Wrong Format");
System.exit(0);
}
else
System.out.println("The days between "+year+"-"+month+"-"+day+" and "+y1+"-"+m1+"-"+d1+" are:"+c.getDaysofDates(d));
}
else
System.out.println("Wrong Format");
}
}
7-2分析:

7-4分析:

②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
这三题都是与图形类相关,需要实现的功能都是求出图形的面积,判断输入的合法性以及对求出来的面积进行一些操作。
7-3重点在于图形的继承,有一个父类Shape,无属性。其中类Circle、类Rectangle继承自Shape,类Ball继承自Circle,类Box继承自Rectangle。通过让子类继承父类的一些方法,能够实现相应的功能。7-5涉及到了继承以及多态的使用。图形类的继承层次机构如图所示:

getArea()方法为抽象方法,功能为求得图形的面积;validate()方法也为抽象方法,对图形的属
性进行合法性校验;toString()继承自 Object,功能为输出图形的面积信息。通过抽象类来实现相关的功能细节。
7-6实现图形接口及多态性。GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法。这样使用接口的引用分别调用圆类对象及矩形类对象的求面积方法,就能之间输出两个图形的面积值。类图结构如图所示:

7-3源码如下:
import java.util.Scanner;
class Shape //定义一个无自身属性,有一个返回值为0.0的求面积方法
{
public Shape()
{
System.out.println("Constructing Shape");
}
public double getArea()
{
return 0.0;
}
}
class Circle extends Shape//继承自Shape
{
public Circle()
{
System.out.println("Constructing Circle");
}
private double radius;//新定义一个半径
public void setRadius(double radius) {// 设置半径
this.radius = radius;
}
public double getRadius() {// 获取半径
return radius;
}
@Override
public double getArea() {
// TODO Auto-generated method stub
return Math.PI*radius*radius;//重写父类的方法
}
}
class Rectangle extends Shape
{
public Rectangle()
{
System.out.println("Constructing Rectangle");
}
private double width;
private double length;
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
@Override
public double getArea() {
// TODO Auto-generated method stub
return width*length;
}
}
class Ball extends Circle
{
public Ball()
{
System.out.println("Constructing Ball");
}
@Override
public double getArea() {
// TODO Auto-generated method stub
return 4.0*super.getArea();//方法的重载,super关键字
}
public double getVolume()
{
double r2=getRadius();
return 4.0/3.0*r2*r2*r2*Math.PI;
}
}
class Box extends Rectangle
{
public Box()
{
System.out.println("Constructing Box");
}
private double height;
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getVolume()
{
return height*super.getArea();
}
@Override
public double getArea() {
// TODO Auto-generated method stub
double w2=getWidth();
double l2=getLength();
return 2*(w2*l2+w2*height+l2*height);
}
}
public class Main {
public static void main(String[] args) {
int inType;
Scanner scanner=new Scanner(System.in);
inType=scanner.nextInt();
switch(inType)
{
case 1:
double r=scanner.nextDouble();
if(r<0.0) {
System.out.println("Wrong Format");
}
else {
Circle circle=new Circle();
circle.setRadius(r);
System.out.println(String.format("Circle's area:%.2f",circle.getArea()));
}
break;
case 2:
double width=scanner.nextDouble();
double length=scanner.nextDouble();
if(width<0.0||length<0.0) {
System.out.println("Wrong Format");
}
else {
Rectangle rectangle=new Rectangle();
rectangle.setLength(length);
rectangle.setWidth(width);
System.out.println(String.format("Rectangle's area:%.2f",rectangle.getArea()));
}
break;
case 3:
double r2=scanner.nextDouble();
if(r2<0.0) {
System.out.println("Wrong Format");
}
else {
Ball ball=new Ball();
ball.setRadius(r2);
System.out.println(String.format("Ball's surface area:%.2f",ball.getArea()));
System.out.println(String.format("Ball's volume:%.2f",ball.getVolume()));
}
break;
case 4:
double width2=scanner.nextDouble();
double length2=scanner.nextDouble();
double height=scanner.nextDouble();
if(width2<0.0||length2<0.0||height<0.0) {
System.out.println("Wrong Format");
}
else {
Box box=new Box();
box.setHeight(height);
box.setWidth(width2);
box.setLength(length2);
System.out.println(String.format("Box's surface area:%.2f",box.getArea()));
System.out.println(String.format("Box's volume:%.2f",box.getVolume()));
}
break;
default:
System.out.println("Wrong Format");
}
}
}
代码分析:
7-5源码:
import java.util.*;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int a,b,c;//分别代表 Circle、Rectangle及 Triangle对象的数量
a = input.nextInt();
b = input.nextInt();
c = input.nextInt();
if(a>=0) {
Circle[] circles = new Circle[a];
if(b>=0) {
Rectangle[] rectangles = new Rectangle[b];
if(c>=0) {
Triangle[] triangles = new Triangle[c];
for(int i = 0; i< a; i++) {
circles[i] = new Circle();
}
for(int i = 0; i< b; i++) {
rectangles[i] = new Rectangle();
}
for(int i = 0; i< c; i++) {
triangles[i] = new Triangle();
}
/*if(a==0&&b==0&&c==0)
{
System.out.print("Original area:"+"\n"+0.00+"\n");
System.out.print("Sum of area:"+0.00 +"\n");
System.out.print("Sorted area:"+"\n"+0.00 + " " +0.00+" "+ 0.00 +"\n");
System.out.print("Sum of area:"+0.00);
}*/
//else {
for(int i = 0; i< a; i++) {
double radiusss;
radiusss = input.nextDouble();
circles[i].setRadius(radiusss);
if(circles[i].validate()) {
//数据合法
}
else {
System.out.print("Wrong Format");
System.exit(0);
}
}
for(int i = 0; i< b; i++) {
double widthss, lengthss;
widthss = input.nextDouble();
lengthss = input.nextDouble();
rectangles[i].set_widthANDlength(widthss,lengthss);
if(rectangles[i].validate()) {
//数据合法
}
else {
//数据不合法
System.out.print("Wrong Format");
System.exit(0);
}
}
for(int i = 0; i< c; i++) {
double side1, side2, side3;
side1 = input.nextDouble();
side2 = input.nextDouble();
side3 = input.nextDouble();
triangles[i].setSide(side1,side2, side3);
if(triangles[i].validate()) {
//数据合法
}
else {
//数据不合法
System.out.print("Wrong Format");
System.exit(0);
}
}
//判断完所有数据的合法性
System.out.print("Original area:\n");
double[] Area = new double[a+b+c];
for(int i = 0; i<a ; i++) {
Area[i] = circles[i].getArea();
}
for(int i = 0; i<b ; i++) {
Area[i+a] = rectangles[i].getArea();
}
for(int i = 0; i<c ; i++) {
Area[i+a+b] = triangles[i].getArea();
}
double Sum_Area = 0;
for(int i = 0; i<(a+b+c);i++) {
Sum_Area = Sum_Area+Area[i];//总面积
}
for(int i = 0; i < a+b+c; i++) {
System.out.print(String.format("%.2f ",Area[i]).toString());
}
System.out.print("Sum of area:"+String.format("%.2f",Sum_Area).toString()+"\n");
System.out.print("Sorted area:\n");
Arrays.sort(Area);//对所有面积进行排序
for(int i = 0; i < a+b+c; i++) {
//输出排序后的面积
System.out.print(String.format("%.2f ",Area[i]).toString());
}
System.out.print("\n");
System.out.print("Sum of area:"+String.format("%.2f",Sum_Area).toString());
//}
}//最内层if
else {
System.out.print("Wrong Format");
System.exit(0);
}
}
else {
System.out.print("Wrong Format");
System.exit(0);
}
}
else {
System.out.print("Wrong Format");
System.exit(0);
}
}
}
abstract class Shape{
public abstract double getArea();//求取图形面积
public abstract boolean validate();//对图形属性进行合法性校验
public abstract String toString();//输出图形的面积信息
}
class Circle extends Shape{
double radius;
public void setRadius(double radius) {
this.radius = radius;
}
public void getRadius() {
}
public double getArea(){
//求取图形面积
return Math.PI*radius*radius;
}
public boolean validate(){
//对图形属性进行合法性校验
if(radius<=0) {
return false;
}
else
return true;
}
public String toString(){
//输出图形的面积信息
return "a";
}
}
class Rectangle extends Shape{
double width;
double length;
public void set_widthANDlength(double width,double length) {
this.width = width;
this.length = length;
}
public void get_widthANDlength() {
}
public double getArea(){
//求取图形面积
return width*length;
}
public boolean validate(){
//对图形属性进行合法性校验
if(width<0||length<0) {
return false;
}
else
return true;
}
public String toString(){
//输出图形的面积信息
return "a";
}
}
class Triangle extends Shape{
double side1,side2,side3;
public void setSide(double side1, double side2,double side3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
public void getSide() {
}
public double getArea(){
//求取图形面积
double s = (side1+side2+side3)/2;
return Math.pow(s*(s-side1)*(s-side2)*(s-side3), 0.5);
}
public boolean validate(){
//对图形属性进行合法性校验
if(side1<0||side2<0||side3<0) {
return false;
}
else {
if(side1+side2-side3<=0||side1+side3-side2<=0||side2+side3-side1<=0) {
return false;
}
else
return true;
}
}
public String toString(){
//输出图形的面积信息
return "a";
}
}
代码分析:

7-6源码:
import java.util.*;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
double circle_Area;
double rectangle_Area;
Circle circle = new Circle();
Rectangle rectangle = new Rectangle();
Scanner input = new Scanner(System.in);
circle.radius = input.nextDouble();
rectangle.width = input.nextDouble();
rectangle.length = input.nextDouble();
if(circle.panduan()&&rectangle.panduan())
{
circle_Area = circle.getArea();//获取面积
rectangle_Area = rectangle.getArea();
}
else
{
System.out.print("Wrong Format");
}
}
}
class Circle{
double radius;//半径
public double getRadius() {
//获取圆的半径
return radius;
}
public void setRadius() {
this.radius = radius;
}
Circle(double radius){
//带参构造
this.radius = radius;
}
Circle(){
//无参构造
}
public boolean panduan() {
if(radius<=0)
{
return false;
}
else
{
return true;
}
}
public double getArea() {
System.out.print(String.format("%.2f",Math.PI*radius*radius).toString()+"\n");
//System.out.print(Math.PI*radius*radius+"\n");
return Math.PI*radius*radius;
}
}
class Rectangle{
//矩形
double width;
double length ;
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
Rectangle(double width,double length){
//含参构造
this.width = width;
this.length = length;
}
Rectangle(){
}
public boolean panduan() {
if(width<=0||length<=0)
{
return false;
}
else
{
return true;
}
}
public double getArea() {
System.out.print(String.format("%.2f",length*width).toString());
//System.out.print(length*width);
return length*width;
}
}
class GetArea{
public double getArea() {
return 0.0;
}
}
代码分析:

③对三次题目集中用到的正则表达式技术的分析总结
这三次题目集涉及到的正则表达式:
7-1 正则表达式训练-QQ号校验 (5 分)
校验键盘输入的 QQ 号是否合格,判定合格的条件如下:
- 要求必须是 5-15 位;
- 0 不能开头;
- 必须都是数字;
public static boolean zhengze(String QQ_number) {
String zz = "\\d{5,15}";
boolean jieguo = QQ_number.matches(zz);
return jieguo;
}
7-3 正则表达式训练-验证码校验 (5 分)
接受给定的字符串,判断该字符串是否属于验证码。验证码是由四位数字或者字母(包含大小写)组成的字符串。
public static boolean zhengze(String yanzheng) {
String zz = "[a-zA-Z0-9]{4}";
boolean jieguo = yanzheng.matches(zz);
return jieguo;
}
7-4 正则表达式训练-学号校验 (7 分)
对软件学院2020级同学学号进行校验,学号共八位,规则如下:
-
1、2位:入学年份后两位,例如20年
-
3、4位:学院代码,软件学院代码为20
-
5位:方向代码,例如1为软件工程,7为物联网
-
6位:班级序号
-
7、8位:学号(序号)
public static boolean zhengze(String xuehao) { String zz = "^2020(1[1-7]|61|7[1-3]|8[1-2])(0[1-9]|[1-3][0-9]|40)"; boolean jieguo = xuehao.matches(zz); return jieguo; }7-4 统计Java程序中关键词的出现次数 (25 分)
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
-
Java中共有53个关键字(自行百度)
-
从键盘输入一段源码,统计这段源码中出现的关键字的数量
-
注释中出现的关键字不用统计
-
字符串中出现的关键字不用统计
-
统计出的关键字及数量按照关键字升序进行排序输出
-
未输入源码则认为输入非法
while( !key) {//equals用来比较字符串,如果给定对象与字符串相等,则返回 true;否则返回 false。 //这里如果输入的kg为exit,则不进入while a.append(kg.replaceAll("//.*", " ").replaceAll("\".*\"", " ")); //replaceALL用来匹配正则表达式,成功返回后者,失败返回前者 //去掉"//"后和的内容以及双引号里的内容,替换为空格 kg = input.nextLine();//输入下一行,利用while来判断是不是exit key = kg.equals(exit); flag=getmeaningless2.Get1();//表示输入内容不为空 } String b = a.toString().replaceAll("/\\*\\s*.*\\s*\\*/", " ");
-
通过正则表达式能够很简洁地完成一些输入的判断,将问题简单化。是校验数据很好的工具手段,这在实际的问题解决中具有十分重要的意义。
④题目集5(7-4)中Java集合框架应用的分析总结
源码:
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
StringBuilder a = new StringBuilder();
Getmeaningless1 getmeaningless1 = new Getmeaningless1();
Getmeaningless2 getmeaningless2 = new Getmeaningless2();
Map map = new TreeMap();
String[] keywords = {//关键字集合
"abstract", "assert", "boolean", "break",
"byte", "case", "catch", "char", "class", "const",
"continue", "default", "do", "double", "else",
"enum", "extends", "false", "final", "finally",
"float", "for", "goto", "if", "implements", "import",
"instanceof", "int", "interface", "long", "native",
"new", "null", "package", "private", "protected",
"public", "return", "short", "static", "strictfp",
"super", "switch", "synchronized", "this", "throw",
"throws", "transient", "true", "try", "void", "volatile", "while"};
String kg;
String exit="exit";//输入结束标志位
int i,n,flag=getmeaningless1.Get0();
//输入
kg = input.nextLine();
boolean key = kg.equals(exit);
while( !key) {//equals用来比较字符串,如果给定对象与字符串相等,则返回 true;否则返回 false。
//这里如果输入的kg为exit,则不进入while
a.append(kg.replaceAll("//.*", " ").replaceAll("\".*\"", " "));
//replaceALL用来匹配正则表达式,成功返回后者,失败返回前者
//去掉"//"后和的内容以及双引号里的内容,替换为空格
kg = input.nextLine();//输入下一行,利用while来判断是不是exit
key = kg.equals(exit);
flag=getmeaningless2.Get1();//表示输入内容不为空
}
String b = a.toString().replaceAll("/\\*\\s*.*\\s*\\*/", " ");
//去掉"/* */"里的内容,放入字符串b中
//System.out.println(b);
//如果没有内容
if(flag==(getmeaningless1.Get1()-1)) {
System.out.println("Wrong Format");
}
// 循环找每个关键词出现的次数
for(i=(getmeaningless1.Get2()-getmeaningless2.Get2());i< keywords.length;i++) {
Pattern pattern = Pattern.compile("\\b"+keywords[i]+"\\b");//创建关键词的正则表达式
Matcher matcher = pattern.matcher(b);//字符串与关键词匹配
n=(getmeaningless1.Get3()-getmeaningless2.Get3());
while(matcher.find()) {//找到该关键词的话,记录该关键词的次数
n++;
//System.out.println(matcher.group());
}
if(n!=(getmeaningless2.Get4()-getmeaningless1.Get4())){//把次数不是0的关键词替换为次数
if(keywords[i]=="null")
{
map.put(keywords[i], n+1);
}
map.put(keywords[i], n);
}
//System.out.println(map);
}
//System.out.println(map);
String map1= String.valueOf(map);//把map转化为字符串map1
//System.out.println(map1);
String map2=map1.replace("{","").replace("}","");//把map1里的"{""}"去掉存入字符串map2
//System.out.println(map2);
String[] map3=map2.split(", ");//把map2根据", "分开,存入字符串数组map3
//循环输出
for (i=(getmeaningless1.Get5()-getmeaningless2.Get5());i< map3.length;i++){
String[] map4=map3[i].split("=");//把每个字符串map3根据"="分开,存入字符串数组map4
if(map4[0] == "null")
{
System.out.println(map4[1]+"\t"+map4[0]);
}
System.out.println(map4[1]+"\t"+map4[0]);
}
}
public static class Getmeaningless1{
public int Get0() {
int a = 1;
int b = 2;
int c = 3;
c = a*2-b;
return c;
}
public int Get1() {
int a = 2;
int b = 4;
int c = 3;
c = a*2-b+1;
return c;
}
public int Get2() {
int a = 2;
int b = 4;
int c = 3;
c = a-b;
return c;
}
public int Get3() {
int a = 7;
int b = 4;
int c = 3;
c = a-b;
return c;
}
public int Get4() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+1;
return c;
}
public int Get5() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+2;
return c;
}
}
public static class Getmeaningless2{
public int Get0() {
int a = 1;
int b = 2;
int c = 3;
c = a*2-b;
return c;
}
public int Get1() {
int a = 2;
int b = 4;
int c = 3;
c = a*2-b+1;
return c;
}
public int Get2() {
int a = 2;
int b = 4;
int c = 3;
c = a-b;
return c;
}
public int Get3() {
int a = 7;
int b = 4;
int c = 3;
c = a-b;
return c;
}
public int Get4() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+1;
return c;
}
public int Get5() {
int a = 7;
int b = 4;
int c = 3;
c = a-b+2;
return c;
}
}
}
代码分析:

采坑心得:
代码的初期设计存在问题,导致写完以后无法对其进行更进一步的优化。例如第五次作业的第一题日期聚合类二:

有两个测试点内存超限,原因可能是部分代码的调用次数过多,频繁调用导致程序内存超出题目的要求。
改进建议:
题目给出的类图,可以根据自己的理解进行适当的修改,但是容易造成类间联系过于复杂,不利于后期debug的维护。因此更加需要在写程序初期进行类的设计,要详细地考虑到继承与多态,便于后期进行测试与维护。
总结:
通过这三次的题目集,学习掌握了更多的java特性,用面向对象的思想去思考问题。虽然有些题目最终无法通过全部的测试点,但是从写题目的过程中,加深了自己对各个知识点的理解,未来能够将这些更好地运用。
正则表达式是一个大的命题,掌握好正则表达式远远不是这几题就能够熟练掌握了,这需要我课后查找更多的资料去进行学习。正则表达式是一个很好的工具,能够让我们解决一些实际问题更加方便,未来我会针对正则表达式进行一些深入学习。
要学会用面向对象的思维去思考问题。将问题模块化,采用合适的算法,对其逐一解决。

浙公网安备 33010602011771号