OOP第二次实验
(1)前言:因为本人表达能力偏弱,可能会写得有些冗长,但是我尽量把我要写的内容写全。
题目集四:题目一看起来很复杂,似乎比求导还要繁琐,但仔细分析,其实只要在分割字符串后对单独项进行检验,之后根据检验结果做出相对应的输出即可。第二题主要考察的是类间的关系设计;第三题主要考察的是类之间的继承。
题目集五:难度上升。其中7-4是对题目集四7-2的升级。
题目集六:前四题是对正则表达式使用的训练,难度不高分值也不高,但我觉得对我来说非常有用。后面两题,尝试提交了很多次,有时是没法全部通过,有时是真的不会。
(2)设计与分析:
题目集4的7-2:用了非常多的类,圈复杂度很高,超出了绿色范围。
类之间结构的设计:


题目集5的7-4的情况相对好一点,7-5的方法数目多,Avg depth等多项值超出范围。


题目集6的7-5、7-6:只有最大圈复杂度一项超出范围。

(2)采坑心得:
- 注重一点一滴的积累,同时加大对难题的练习。
- 不要老是想着用以前的知识解决现在的问题,比如说在题目集五中的第四题,在输出方面如果使用以前的方法就会得不到正确答案,所以需要运用新学的知识点去解决。
(源码)import java.util.Scanner;
import java.util.Scanner;
//Year类
class Year{
int value;
//默认构造方法
public Year(){
}
//带参构造方法
public Year(int value){
this.value=value;
}
//getter
public int getValue(){
return value;
}
//setter
public void setValue(int value){
this.value=value;
}
//判断year是否为闰年
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(){
value=value+1;
}
//年份减一
public void yearReduction(){
value=value-1;
}
}
//Month类
class Month{
int value;
Year year;
//默认构造方法
public Month(){
}
//带参构造方法
public Month(int yearValue,int monthValue){
this.year=new Year(yearValue);
this.value=monthValue;
}
//getter
public int getValue(){
return value;
}
public Year getYear(){
return year;
}
//setter
public void setValue(int value){
this.value=value;
}
public void setYear(Year year){
this.year=year;
}
//日期复位(1)
public void resetMin(){
value=1;
}
//月份设置为12
public void resetMax(){
value=12;
}
//效验数据合法性
public boolean validate(){
if(value>=1&&value<=12)
return true;
else
return false;
}
//月份加一
public void dayIncrement(){
value=value+1;
}
//月份减一
public void dayReduction(){
value=value-1;
}
}
//Day类
class Day{
int value;
Month month;
int a[]={31,28,31,30,31,30,31,31,30,31,30,31};
//默认构造方法
public Day(){
}
//带参构造方法
public Day(int yearValue,int monthValue,int dayValue){
this.month=new Month(yearValue,monthValue);
this.value=dayValue;
}
//getter
public int getValue(){
return value;
}
public Month getMonth(){
return month;
}
//setter
public void setValue(int value){
this.value=value;
}
public void setMonth(Month value){
this.month=value;
}
//日期复位(1)
public void resetMin(){
value=1;
}
//日期设为该月最大值
public void resetMax(){
value=a[month.getValue()-1];
}
//效验数据合法性
public boolean validate(){
if(this.getMonth().getYear().isLeapYear())
a[1]=29;
if(value>=1&&value<=a[month.getValue()-1])
return true;
else
return false;
}
//日期加一
public void dayIncrement() {
value=value+1;
}
//日期减一
public void dayReduction() {
value=value-1;
}
}
//DateUtil类
class DateUtil{
Day day;
//默认构造方法
public DateUtil(){
}
//带参构造方法
public DateUtil(int d,int m,int y){
this.day=new Day(d,m,y);
}
//getter
public Day getDay(){
return day;
}
//setter
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;
}
//判定两个日期是否相等
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,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;
}
//求下n天
public DateUtil getNextNDays(int 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);
}
//求前n天
public DateUtil getPreviousNDays(int 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;
}
}
//主类
public class Main {
public static void main(String[] args) {
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");
}
}
测试数据及结果:
输入:2018 6 19 8
输出:8 days ago is:2018-6-11
输入:2018 6 19 -8
输出:-8 days ago is:2018-6-27
实验三7-2:import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int a=input.nextInt();//year
int b=input.nextInt();//month
int c=input.nextInt();//day
Date date = new Date();
if(date.checkInputValidity(a,b,c)) {
System.out.println("Date Format is Wrong");
}
else {
date.getNextDay(a,b,c);
}
}
}
class Date {
Scanner input=new Scanner(System.in);
private int day=0;
private int month=0;
private int year=0;
private int[] tian={0,31,28,31,30,31,30,31,31,30,31,30,31};
public Date() {
super();
// TODO Auto-generated constructor stub
}
public Date(int day, int month, int year) {
super();
this.day = day;
this.month = month;
this.year = year;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public boolean isLeapYear(int year) {
return (year%4==0&&year%100!=0||year%400==0);
} //判断闰年
public boolean checkInputValidity(int year,int month,int day) {
return (year<1900||year>2000||month<1||month>12||day<1||day>31||isLeapYear(year)==false&&month==2&&day==29);
} //当输入无效时返回真值
public void getNextDay(int year,int month,int day) {
int n;
if(isLeapYear(year)){
n=29;
}
else{
n=28;
}
if(month==1&&day==31||month==3&&day==31||month==5&&day==31||month==7&&day==31||month==8&&day==31||month==10&&day==31){
month++;
System.out.println("Next day is:"+year+"-"+month+"-"+"1");
}
else if(month==4&&day==30||month==6&&day==30||month==9&&day==30||month==11&&day==30){
month++;
System.out.println("Next day is:"+year+"-"+month+"-"+"1");
}
else if(month==12&&day==31){
year++;
System.out.println("Next day is:"+year+"-"+1+"-"+"1");
}
else if(month==2&&day==n)
{
month++;
System.out.println("Next day is:"+year+"-"+month+"-"+"1");
}
else{
day++;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
}
}
}
测试样例及结果:
输入:1912 12 25
输出:Next day is:1912-12-26
输入:2001 2 30
输出:Date Format is Wrong
(2)改进建议:1.一个if语句就可以让圈复杂度飚出绿色范围了,今后我会少用if,尽量用switch语句代替需要判断的部分。
(5)总结:对本阶段三次题目集的综合性总结,学到了什么,哪些地方需要进一步学习及研究,对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见。
第一次实验虽然简单,但是也花费了不少时间。那道计算税率的题的数据实在太多了,我有一个点一直过不去,检查了很久才发现是有一个数字输错了。
我想说,题量越多,时间越短反而让人越安心呢。一旦题目开始变少,难度简直直线上升,第三次的第三道题,就算时间再充裕,我也根本没有头绪,愁如何下手。在这道题之前,我遇到什么问题还可以看看书,逛逛博客,问问同学。做完之后哇好有成就感,觉得自己学到的真多呢,哪里哪里还可以改进哦。但是那最后一题,我拿命去写都写不出来啊,就完全没接触过、甚至见都没见过正则表达式,脑子里一点概念也没有。去百度上找了很多材料很多代码看,每次觉得学会了,一写一测试就是编译错误,或是运行结果错误。而且仅凭我那皮毛都算不上的学习,根本无法实现题目需要的判断。其实这个求导算法本身不复杂,多种要求混合增加了它的难度,我卡到天荒地老,根本写不出来。我的自学能力确实很欠缺,不得其法,要是老师有空可以预先讲解一下这样陌生的知识点,引导我们上手。
浙公网安备 33010602011771号