oop题目集1~3的总结性Blog

发布时间 2023-03-26 20:29:09作者: xzs2004

一、前言

从题目集1-3的训练后对java的基本语法有了一个大致的掌握,在pta的训练中明显的感受到题目的知识点,难度,和联系都是紧密相关连的。

训练集1

这次的作业主要是让我们练习并掌握java基础的语法,题目量偏大,但题目难度不高
7-1:计算年利率和7-2:身体质量指数(BMI)测算
练习了对java中数据的输入和输出,练习了java中的选择结构,同时知道了如何保留两位小数输出浮点型数据。
7-3:九九乘法表
练习了java中的循环结构,加深了对println()和print()的理解,该题目主要通过双循环解决问题。
7-4:快递运费
练习了如何四舍五入保留数据,练习了如何强制转化数据类型。
7-5:去掉重复的字符 7-6:统计一个子串在整串中出现的次数 7-7:有重复的数据 7-8:从一个字符串中移除包含在另一个字符串中的字符
练习了对字符串的基本操作语法。
7-9:Prime Numbers 7-10:GPS数据处理 7-11:求定积分 7-12:列出最简真分数序列
练习了对算法的构建,对题目问题的理解和细化。

训练集2

这次作业练习了各种结构之间的嵌套,加强了对语法的掌握,题目量较高,难度比起上一次训练集更复杂一些,尤其的最后两道题,训练了自己对问题的思考和拆分能力。
7-1到7-7
主要练习了算法的构造,循环选择结构的嵌套,和对字符串的操作。
7-8 判断三角形类型和7-9 求下一天
练习了方法的构造,方法的调用,练习了该如何将一个复杂的问题简单化,将问题逐步分解再逐步解决的过程。

训练集3

这次作业主要练习了类的构造方法,类中方法的构建,方法的调用,和方法的重构。
7-1 创建圆形类 7-2 创建账户类Account
练习了类的构造和类中属性的设置,和方法的构建,练习了类中的参数传递过程。
7-3 定义日期类 7-4 日期类设计
这两道题主要是对于训练集7-9的优化和扩展,引入了类的使用和进一步对类内属性进行操作,增添了更多算法。

二、设计分析

(1)7-3定义日期类

image
源码

点击查看代码


import java.util.Scanner;

class Data {
private int year;
private int month;
private int day;
static int[] mon_maxnum= new int[] {0,31,29,31,30,31,30,31,31,30,31,30,31};
static int[] mon_maxnum2= new int[] {0,31,28,31,30,31,30,31,31,30,31,30,31};
	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 static boolean isLeapYear(int year){                            
    if(year%4==0&&year%100!=0||year%400==0)
        return true;
    else return false;
};
public static boolean checkInputValidity(int year,int month,int day){
	if(Data.isLeapYear(year)){
		if(year>=1900&&year<=2000&&month>=1&&month<=12&&day<=mon_maxnum[month]&&day>0)
	     return true;
	    else return false;}
	else {
		if(year>=1900&&year<=2000&&month>=1&&month<=12&&day<=mon_maxnum2[month]&&day>0) {
		return true;}
		else return false;
	}
}
public static void nextDate(int year,int month,int day){
	if(Data.isLeapYear(year)){
		if(month==12&&day==31) {
			year++;
			month=1;
			day=1;
		}
			
	
	else if(day==mon_maxnum[month]) {
			day=1;
		    month++;
		}
	else day++;}
	else {
			if(month==12&&day==31) {
				year++;
				month=1;
				day=1;
			}
				
		
		else if(day==mon_maxnum2[month]) {
				day=1;
			    month++;
			}
		else day++;
		}
	System.out.println("Next day is:"+year+"-"+month+"-"+day);
	}

}


public class Main{
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
Scanner in=new Scanner(System.in);
int year=in.nextInt();
int month=in.nextInt();
int day=in.nextInt();
if(Data.checkInputValidity(year,month,day)) {
	Data.nextDate(year,month,day);
}
else System.out.println("Date Format is Wrong");
		
	}

}

该题目要求在一行内输入年月日的值,
当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
当输入日期合法,输出下一天,格式如下:Next day is:年-月-日
这道题需要我们定义一个类data,存放属性年月日。
同时要求我们使用方法的重构来初始化对象。

通过SourceMonitor分析的数据图
image
发现了以下几个问题:
1.代码注释过少。
结合SourceMonitor生成的图像image
我发现了以下问题:
1.代码复杂度高,这主要原因是因为在方法getNextedate()使用了大量if语句来判断每种情况不同的操作步骤,这使得代码可读性低,复杂度高。但其中如果仔细分析可以减少代码行数。

(2)7-4日期类设计

image

这道题要求要求下n天后的日期和上n天的日期和两个日期的间隔多少天.
通过SourceMonitor分析的数据图
image
发现各项参考数据都超过了正常值。
而问题主要出在求两个日期时使用大量判断语句导致结构复杂,可以通过思考后降低复杂度。

点击查看代码
public int getDaysofDates(DateUtil date) {
	int num=0;
	if(equalTwoDates(date))
		return 0;
	else {
		if(compareDates(date)) {
			if(this.year-date.year==1) {
			if(isLeapYear(date.year)) {
				num=mon_maxnum[date.month]-date.day;
				for(int i=date.month+1;i<=12;i++) {
					num=num+mon_maxnum[i];
				}
			}
			else {
				num=mon_maxnum2[date.month]-date.day;
				for(int i=date.month+1;i<=12;i++) {
					num=num+mon_maxnum2[i];
			}}
				if(isLeapYear(this.year)) {
				for(int i=1;i<this.month;i++)	
					num=num+mon_maxnum[i];
			}
				else {
					for(int i=1;i<this.month;i++)
						num=num+mon_maxnum2[i];
				
	
		}
			num=num+this.day;
		}
			else if(this.year-date.year==0) {
				if(this.month==date.month) {
				num=this.day-date.day;
			}
			else{
				if(isLeapYear(date.year)) {
					num=mon_maxnum[date.month]-date.day+this.day;
					for(int i=date.month+1;i<this.month;i++) {
						num=num+mon_maxnum[i];
					}
				}
				else {
					num=mon_maxnum2[date.month]-date.day+this.day;
					for(int i=date.month+1;i<this.month;i++) {
						num=num+mon_maxnum2[i];
					
				}
				
			}
			}}
			else if(this.year-date.year>1) {
				if(isLeapYear(date.year)) {
					num=mon_maxnum[date.month]-date.day;
					for(int i=date.month+1;i<=12;i++) {
						num=num+mon_maxnum[i];
					}
				}
				else {
					num=mon_maxnum2[date.month]-date.day;
					for(int i=date.month+1;i<=12;i++) {
						num=num+mon_maxnum2[i];
				}}
					if(isLeapYear(this.year)) {
					for(int i=0;i<this.month;i++)
						num=num+mon_maxnum[i];
				}
					else {
						for(int i=0;i<this.month;i++)
							num=num+mon_maxnum2[i];
					}
			
				for(int i=date.year+1;i<this.year;i++) {
					if(isLeapYear(i))
						num=num+366;
					else num=num+365;
				
				
			}
				
			num=num+this.day;
			}

		}
		else {
			if(date.year-this.year==1) {
				if(isLeapYear(this.year)) {
					num=mon_maxnum[this.month]-this.day;
					for(int i=this.month+1;i<=12;i++) {
						num=num+mon_maxnum[i];
					}
				}
				else {
					num=mon_maxnum2[this.month]-this.day;
					for(int i=this.month+1;i<=12;i++) {
						num=num+mon_maxnum2[i];
				}}
					if(isLeapYear(date.year)) {
					for(int i=0;i<date.month;i++)
						num=num+mon_maxnum[i];
				}
					else {
						for(int i=0;i<date.month;i++)
							num=num+mon_maxnum2[i];
					}
		num=num+date.day;
			}
				

				else if(date.year-this.year==0) {
					if(date.month==this.month) {
						num=date.day-this.day;
					}
					else {
					if(isLeapYear(this.year)) {
						num=mon_maxnum[this.month]-this.day+date.day;
						for(int i=this.month+1;i<date.month;i++) {
							num=num+mon_maxnum[i];
						}
					}
					else {
						num=mon_maxnum2[this.month]-this.day+date.day;
						for(int i=this.month+1;i<date.month;i++) {
							num=num+mon_maxnum2[i];
						
					}
					
				}
				}
				}
				else if(date.year-this.year>1) {
					if(isLeapYear(this.year)) {
						num=mon_maxnum[this.month]-this.day;
						for(int i=this.month+1;i<=12;i++) {
							num=num+mon_maxnum[i];
						}
					}
					else {
						num=mon_maxnum2[this.month]-this.day;
						for(int i=this.month+1;i<=12;i++) {
							num=num+mon_maxnum2[i];
					}}
						if(isLeapYear(date.year)) {
						for(int i=1;i<date.month;i++)
							num=num+mon_maxnum[i];
					}
						else {
							for(int i=1;i<date.month;i++)
								num=num+mon_maxnum2[i];
						}
				
					for(int i=this.year+1;i<date.year;i++) {
						if(isLeapYear(i))
							num=num+366;
						else num=num+365;	
					
					
				}
					
				num=num+date.day;
				}
			
		}
	}
此方法非常复杂,设计思路不符合计算机运行规则,应该进行优化

三、踩坑心得

1.做训练集一的时候总是因为精度问题过不了测试点。
解决方法:double型强转float型,或者使用String.format()函数。
2.写pta时一股脑去做,结果浪费了很多时间卡在题目上。
解决方法:在遇到问题先不着急,先系统性学习一遍再做会迅速很多。
3.在进行相邻数组内数据比较时候,发生数组越界问题。
解决方法:先理清比较过程,导致变量超出数组范围,将循环判断条件i转变为i-1解决。
image

4.在判断等边直角三角形时,一直判断不了。
解决方法:在分析第三边时发现第三边永远是无理数,所以在判断时取近似值进行比较,才比较成功
if((Math.pow(side1,2)+Math.pow(side2,2)-Math.pow(side3,2)<0.1)||(Math.pow(side2,2)+Math.pow(side3,2)-Math.pow(side1,2)<0.1)||(Math.pow(side1,2)+Math.pow(side3,2)-Math.pow(side2,2)<0.1)) System.out.println("Isosceles right-angled triangle");
5.在设计求两个日期相差天数时,时间计算总是出现问题。
解决方法:对代码进行debug关注设置的变量的值的变化,加深了对局部变量的认识,同时找到了因为局部变量设置错误导致的代码运行异常。

点击查看代码




public int getDaysofDates(DateUtil date) {


	int num=0;
	if(equalTwoDates(date))
		return 0;
	else {
		if(compareDates(date)) {
			if(this.year-date.year==1) {
			if(isLeapYear(date.year)) {
				num=mon_maxnum[date.month]-date.day;
				for(int i=date.month+1;i<=12;i++) {
					num=num+mon_maxnum[i];
				}
			}
			else {
				num=mon_maxnum2[date.month]-date.day;
				for(int i=date.month+1;i<=12;i++) {
					num=num+mon_maxnum2[i];
			}}
				if(isLeapYear(this.year)) {
				for(int i=1;i<this.month;i++)	
					num=num+mon_maxnum[i];
			}
				else {
					for(int i=1;i<this.month;i++)
						num=num+mon_maxnum2[i];
				
	
		}
			num=num+this.day;
		}
			else if(this.year-date.year==0) {
				if(this.month==date.month) {
				num=this.day-date.day;
			}
			else{
				if(isLeapYear(date.year)) {
					num=mon_maxnum[date.month]-date.day+this.day;
					for(int i=date.month+1;i<this.month;i++) {
						num=num+mon_maxnum[i];
					}
				}
				else {
					num=mon_maxnum2[date.month]-date.day+this.day;
					for(int i=date.month+1;i<this.month;i++) {
						num=num+mon_maxnum2[i];
					
				}
				
			}
			}}
			else if(this.year-date.year>1) {
				if(isLeapYear(date.year)) {
					num=mon_maxnum[date.month]-date.day;
					for(int i=date.month+1;i<=12;i++) {
						num=num+mon_maxnum[i];
					}
				}
				else {
					num=mon_maxnum2[date.month]-date.day;
					for(int i=date.month+1;i<=12;i++) {
						num=num+mon_maxnum2[i];
				}}
					if(isLeapYear(this.year)) {
					for(int i=0;i<this.month;i++)
						num=num+mon_maxnum[i];
				}
					else {
						for(int i=0;i<this.month;i++)
							num=num+mon_maxnum2[i];
					}
			
				for(int i=date.year+1;i<this.year;i++) {
					if(isLeapYear(i))
						num=num+366;
					else num=num+365;
				
				
			}
				
			num=num+this.day;
			}

		}
		else {
			if(date.year-this.year==1) {
				if(isLeapYear(this.year)) {
					num=mon_maxnum[this.month]-this.day;
					for(int i=this.month+1;i<=12;i++) {
						num=num+mon_maxnum[i];
					}
				}
				else {
					num=mon_maxnum2[this.month]-this.day;
					for(int i=this.month+1;i<=12;i++) {
						num=num+mon_maxnum2[i];
				}}
					if(isLeapYear(date.year)) {
					for(int i=0;i<date.month;i++)
						num=num+mon_maxnum[i];
				}
					else {
						for(int i=0;i<date.month;i++)
							num=num+mon_maxnum2[i];
					}
		num=num+date.day;
			}
				

				else if(date.year-this.year==0) {
					if(date.month==this.month) {
						num=date.day-this.day;
					}
					else {
					if(isLeapYear(this.year)) {
						num=mon_maxnum[this.month]-this.day+date.day;
						for(int i=this.month+1;i<date.month;i++) {
							num=num+mon_maxnum[i];
						}
					}
					else {
						num=mon_maxnum2[this.month]-this.day+date.day;
						for(int i=this.month+1;i<date.month;i++) {
							num=num+mon_maxnum2[i];
						
					}
					
				}
				}
				}
				else if(date.year-this.year>1) {
					if(isLeapYear(this.year)) {
						num=mon_maxnum[this.month]-this.day;
						for(int i=this.month+1;i<=12;i++) {
							num=num+mon_maxnum[i];
						}
					}
					else {
						num=mon_maxnum2[this.month]-this.day;
						for(int i=this.month+1;i<=12;i++) {
							num=num+mon_maxnum2[i];
					}}
						if(isLeapYear(date.year)) {
						for(int i=1;i<date.month;i++)
							num=num+mon_maxnum[i];
					}
						else {
							for(int i=1;i<date.month;i++)
								num=num+mon_maxnum2[i];
						}
				
					for(int i=this.year+1;i<date.year;i++) {
						if(isLeapYear(i))
							num=num+366;
						else num=num+365;	
					
					
				}
					
				num=num+date.day;
				}
			
		}
	}
	
	return num;
}

6.进行两个类似方法描写时直接采用复制在修改的方式,导致代码出错。
解决方法:用debug去检测变量的值,找出问题所在再慢慢修改。

四、改进建议

1.代码设计冗长,使用了大量判断语句导致代码可读性极差。
2.变量名称定义不规范,不同方法之间的间隔太短导致区别算法过难。
3.在遇到问题后想着先去编程,并未仔细思考代码实现方案,导致部分简单的代码想的过于复杂,而导致代码冗长。
4.代码中注释太少,应该增加更多代码注释,提高代码可读性。

五、总结

这次的训练集提高了我对java基础语法的掌握程度,让我逐渐摸索适应java的学习方式,学会了定义一段代码优越性的基本标准,学会了怎么通过debug功能去找到自己代码的逻辑错误,学会了大致如何使用ecslip的方法,学到了快捷创建对属性获取和初始化的方法,还需加强对debug功能的熟悉程度,同时加强代码的可读性减少冗长代码的出现,在遇到问题时先分析问题再想到解决方法,找到简单的解决方法。同时了解到java语言学习方式和c语言学习方式的不同,java语言的语法部分需要我们不断自主学习,更注重自主学习方式,和学习效率,强度较c语言更高,而进阶知识则通过老师的讲解和自身的不断练习来找到其中的关系。同时感觉到java作业的强度层层递进,且密切相关,需要我们及时更进,对我们的要求更高。