OO第一次博客作业
前言:
前三次的题目的难度感觉得到是有逐渐增长的。第一次的题集内容都比较基础,是一些简单的java语法的运用,题目数量比较多,但是难度不算很高,7-4的繁琐反而比较难的7-8需求的时间更长,错了就需要慢慢核验;第二次题集内容也不是很难,基本上涉及的数组,字符等问题,都还算好解决,后面三道题循序渐进,当时每做一道就对前一道的代码进行修改,能感受到一点代码渐渐完善的成就感(乐;第三次题集开始要求类的封装了,考察的也主要是类和对象这一方面,做的时候也还好,就是最后一题还是很有难度的。
设计与分析:
输入三角形三条边,判断该三角形为什么类型的三角形。
输入格式:
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。
输出格式:
(1)如果输入数据非法,则输出“Wrong Format”; (2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”; (3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”; (3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”; (5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”; (6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”; (7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。
1 import java.util.*; 2 public class Main{ 3 public static void main(String[] args){ 4 Scanner cin=new Scanner(System.in); 5 double a=cin.nextDouble(); 6 double b=cin.nextDouble(); 7 double c=cin.nextDouble();//输入三边数据 8 if((a>=1&&a<=200)&&(b>=1&&b<=200)&&(c>=1&&c<=200)){//判断数据是否合法 9 if(a+b>c&&a+c>b&&b+c>a){//判断是否构成三角形 10 if(a==c&&b==c){//等边 11 System.out.println("Equilateral triangle"); 12 } 13 else if(((a==b)||(b==c)||(a==c))&&((a*a+b*b!=c*c)||(c*c+b*b!=a*a)||(a*a+c*c!=b*b))){//非直角等腰 14 System.out.println("Isosceles triangle"); 15 } 16 else if(((a*a*2-c*c<=0.00001)&&(a==b))||((2*c*c-a*a<=0.00001)&&(b==c))||((2*a*a-b*b<=0.00001))&&(a==c))){//等腰直角 17 System.out.println("Isosceles right-angled triangle"); 18 } 19 else if((a*a+b*b==c*c)||(c*c+b*b==a*a)||(a*a+c*c==b*b)){//直角 20 System.out.println("Right-angled triangle"); 21 } 22 else 23 System.out.println("General triangle");//普通三角形 24 } 25 else 26 System.out.println("Not a triangle");//不能构成三角形 27 } 28 else 29 System.out.println("Wrong Format");//非法数据 30 } 31 }
本题目主要是输入三个类型为double(就是因为这个点,有些三角形三边为根号不能完全贴合条件,需要留出容错)的值作为三角形的三边,让我们判断其类型,并输出判断。做这个题目的时候使用了很多if-else嵌套循环,首先是判断数据的合法,接着是判断是否三角形,接着进行分类,考虑到等腰直角同属于两边,一开始是在内部进行嵌套循环,进行等边,等腰直角,等腰,直角这样的顺序,但觉得这样有些繁琐,就将条件细化全部改为了一个层次上的if-else。
分析SourceMonitor给出的图可得本次的代码的注释有些多了,或许应删去部分容易理解处的代码注释;类中方法数很低,本次还未完全进入面对对象编程的内容中,主体还是熟悉java语法,所以在自身看来可以理解;最高复杂度和平均复杂度都偏高,但这次恰好考核if-else嵌套循环,之后会注意代码是否仍复杂度高并对此做出改善,降低其崩溃出错的风险;其他属性由图看来还算是合格。
输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法。
要求:Main类中必须含有如下方法,签名如下:
public static void main(String[] args);//主方法
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
- 当输入数据非法及输入日期不存在时,输出“Wrong Format”;
- 当输入日期合法,输出下一天,格式如下:Next date is:年-月-日
1 import java.util.*; 2 public class Main{ 3 public static boolean isLeapYear(int year) {//判断year是否为闰年,返回boolean类型; 4 boolean isLeapYear=(year%4==0&&year%100!=0)||year%400==0; 5 return isLeapYear; 6 } 7 public static boolean checkInputValidity(int year,int month,int day){//判断输入日期是否合法,返回布尔值 8 int[] leapmon=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年月份对应日期 9 int[] mon=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};//平年月份对应日期 10 if(year>=1820&&year<=2020){//年份合法 11 if(month>=1&&month<=12){//月份合法 12 if(isLeapYear(year)){//区分判断是否存在该天 13 if(day<=leapmon[month]&&day>=1){ 14 return true; 15 } 16 else 17 return false; 18 } 19 else if(day<=mon[month]&&day>=1){ 20 return true; 21 } 22 else 23 return false; 24 } 25 else 26 return false; 27 } 28 else 29 return false; 30 } 31 public static void nextDate(int year,int month,int day){//求输入日期的下一天 32 int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; 33 if(isLeapYear(year)) 34 a[2]=29; 35 if(checkInputValidity(year,month,day)){ 36 if(month==12){//考虑跨年情况 37 if(day==a[month]){ 38 year+=1; 39 month=1; 40 day=1; 41 } 42 else 43 day+=1; 44 } 45 else{ 46 if(day==a[month]){ 47 month+=1; 48 day=1; 49 } 50 else 51 day+=1; 52 } 53 System.out.println("Next date is:"+year+"-"+month+"-"+day); 54 } 55 else 56 System.out.println("Wrong Format"); 57 } 58 public static void main(String[] args){//主方法; 59 Scanner cin=new Scanner(System.in); 60 int year=cin.nextInt(); 61 int month=cin.nextInt(); 62 int day=cin.nextInt(); 63 nextDate(year,month,day); 64 } 65 }
本题是输入三个整型数分别作为年月日,然后求这个日期的下一天并输出,按照题目要求需要写出这四个方法,首先主方法可以忽略,因为其内容大概率只需要接受输入,调用函数以及输出结果;判断是否为闰年的方法进行一个简单的if判断并返回布尔值;判断输入日期合法则用if-else嵌套层层判断即可,但要注意每个分支都应有对应的返回值;求下一天是最主要的函数,需要进行分类别的判断(跨年,跨月之类),只要仔细,这道题应该不存在问题,并且它还有前一题做铺垫,理应在前一题便写好了几个有用的函数。
public static void main(String[] args);//主方法
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
![]()
分析SourceMonitor给出的图可得本次代码的类中方法数还是很低,还是没有进入类与对象的部分,所以也可理解;最高复杂度和平均复杂度依然偏高,主要还是判断下一天和判断日期是否合法运用到的if-else都拉高了,以后尽量做到降低复杂度,降低风险,也更便于维护;这次代码的块平均深度也偏高了,说明仍需要对代码进行此方面的优化。
输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。
输入格式:
在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。
输出格式:
- 当输入的年、月、日以及n的值非法时,输出“Wrong Format”;
- 当输入数据合法时,输出“n days ago is:年-月-日”
1 import java.util.*; 2 public class Main{ 3 public static boolean isLeapYear(int year) {//判断year是否为闰年,返回boolean类型; 4 boolean isLeapYear=(year%4==0&&year%100!=0)||year%400==0; 5 return isLeapYear; 6 } 7 public static boolean checkInputValidity(int year,int month,int day){//判断输入日期是否合法,返回布尔值 8 int[] leapmon=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年月份对应日期 9 int[] mon=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};//平年月份对应日期 10 if(year>=1820&&year<=2020){//年份合法 11 if(month>=1&&month<=12){//月份合法 12 if(isLeapYear(year)){//区分判断是否存在该天 13 if(day<=leapmon[month]&&day>=1){ 14 return true; 15 } 16 else 17 return false; 18 } 19 else if(day<=mon[month]&&day>=1){ 20 return true; 21 } 22 else 23 return false; 24 } 25 else 26 return false; 27 } 28 else 29 return false; 30 } 31 public static void nextDate(int year,int month,int day,int n){//求输入日期的前或后n天 32 int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; 33 int m=month; 34 int d=day; 35 if(isLeapYear(year)) 36 a[2]=29; 37 if(n<=10&&n>=-10){//数据合法 38 if(checkInputValidity(year,month,day)){ 39 if(month==12){//考虑跨年情况 40 if(day-n>=1&&day-n<=a[month]) 41 d-=n; 42 else if(day-n>=31){ 43 year+=1; 44 m=1; 45 d=day-n-31; 46 } 47 else{ 48 m-=1; 49 d=a[month-1]+day-n; 50 } 51 } 52 else if(month==1){//考虑跨年情况 53 if(day-n>=1&&day-n<=a[month]) 54 d-=n; 55 else if(day-n<=a[month]){ 56 year-=1; 57 m=12; 58 d=31+day-n; 59 } 60 else{ 61 m+=1; 62 d=day-n-a[month]; 63 } 64 } 65 else{ 66 if(day-n>=1&&day-n<=a[month]) 67 d-=n; 68 else if(day-n>=a[month]){ 69 m+=1; 70 d=day-n-a[month]; 71 } 72 else{ 73 m-=1; 74 d=a[month-1]+day-n; 75 } 76 } 77 System.out.println(n+" days ago is:"+year+"-"+m+"-"+d); 78 } 79 else 80 System.out.println("Wrong Format"); 81 } 82 else 83 System.out.println("Wrong Format"); 84 } 85 public static void main(String[] args){//主方法; 86 Scanner cin=new Scanner(System.in); 87 int year=cin.nextInt(); 88 int month=cin.nextInt(); 89 int day=cin.nextInt(); 90 int n=cin.nextInt(); 91 nextDate(year,month,day,n); 92 } 93 }
本题目是输入四个整型数分别作为年月日,以及日期变化的度量n(此时就应注意到n与中间计算日期时的符号正负问题),计算该日期n天后的日期并输入。作为本次题集的最后一道题,并且有前两道题的铺垫,只需要将上一题求下一天的函数修改为n天后的函数,因为n有正负,所以比起之前需要额外判断1月,即回退到上一年的情况,并且判断的范围也需要加入n这个变量来判断月份的变化,第一遍写的时候基本完成了逻辑,进行一些微小的修正就完成了。
分析SourceMonitor给出的图可得本次代码在注释上(程序判断中)缺失很多,可能是因为直接对上一题函数进行修改,在函数的修改时因为自己对逻辑的了解忽略了注释这一项,以后还是应该保证注释的量,主要为了他人更易懂,方便理解交流;然后是老问题,最高复杂度和平均复杂度,比之前‘更胜一筹’,应该是判断n天后的if-else循环嵌套比之前的更复杂了一点,emmm以后其他类型的题目尽量控制一下;
然后平均每个函数包含的语句也偏多了,应该也是if-else部分增加了大段代码,造成其增长,以后说不定可以将其拆分,让代码更加简洁一些。
定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
要求:Date类结构如下图所示:
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
- 当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
- 当输入日期合法,输出下一天,格式如下:Next day is:年-月-日
import java.util.*; class Date{ static int year; static int month; static int 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 static boolean isLeapYear(int year) {//判断year是否为闰年,返回boolean类型; boolean isLeapYear=(year%4==0&&year%100!=0)||year%400==0; return isLeapYear; } public static boolean checkInputValidity(int year,int month,int day){//判断输入日期是否合法,返回布尔值 int[] leapmon=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年月份对应日期 int[] mon=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};//平年月份对应日期 if(year>=1900&&year<=2000){//年份合法 if(month>=1&&month<=12){//月份合法 if(isLeapYear(year)){//区分判断是否存在该天 if(day<=leapmon[month]&&day>=1){ return true; } else return false; } else if(day<=mon[month]&&day>=1){ return true; } else return false; } else return false; } else return false; } public static void nextDate(int year,int month,int day){//求输入日期的下一天 int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; if(isLeapYear(year)) a[2]=29; if(checkInputValidity(year,month,day)){ if(month==12){//考虑跨年情况 if(day==a[month]){ year+=1; month=1; day=1; } else day+=1; } else{ if(day==a[month]){ month+=1; day=1; } else day+=1; } System.out.println("Next day is:"+year+"-"+month+"-"+day); } else System.out.println("Date Format is Wrong"); } } public class Main{ public static void main(String[] args){ Scanner cin=new Scanner(System.in); Date a=new Date(); a.setYear(cin.nextInt()); a.setMonth(cin.nextInt()); a.setDay(cin.nextInt()); a.nextDate(a.getYear(),a.getMonth(),a.getDay()); } }
本题目依旧是输入三个整型数作为年月日输出下一天,不过在本次题目里终于是开始了封装的概念,将对象和函数都放于其他类中,需要注意的是public以及static来便于应用,总之还是可以拿上次的题目来进行修改,所以也没费什么心思就完成了。
分析SourceMonitor给出的图可得进行了封装之后,很多数据都有了改善,虽然这个最大复杂度还是偏高,虽然这个代码注释量垫底了(可以理解嘛毕竟这相当于上一次的直接修改,所以很顺畅就写完了,没什么留注释的空间),总体来说这次也算是初次进行封装题目的练习,也没有其他说明了。
编写程序性,实现对简单多项式的导函数进行求解。详见作业指导书。
输入格式:
在一行内输入一个待计算导函数的表达式,以回车符结束。
输出格式:
- 如果输入表达式不符合上述表达式基本规则,则输出“Wrong Format”。
- 如果输入合法,则在一行内正常输出该表达式的导函数,注意以下几点: 结果不需要排序,也不需要化简;
- 当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
- 当输出结果第一项系数符号为“+”时,不输出“+”;
- 当指数符号为“+”时,不输出“+”;
- 当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可。
输出格式见输入输出示例。
这道题当时是没什么思路就搁置了。。。结果到最后也没写什么出来,后面正则表达式倒是进行了一定的学习,有些似懂非懂了,尝试了下写这道题,还是不太行(主要还是时间,拖延要不得),就没什么说的了,可能以后老师把它当例题讲一下,或者就是后续学习的时候请教下班内高人了,总之这道题学到了些正则的内容还是可以的。
放上一个摸鱼两个点的码(一开始没写的时候就写了个这个是不是有什么问题,说不定没写这个后面还能努力点写)
1 import java.util.*; 2 class Main{ 3 public static void main(String[] args){ 4 Scanner cin=new Scanner(System.in); 5 String str=cin.nextLine(); 6 System.out.print("Wrong Format"); 7 } 8 }
采坑心得:
1.首先是第一次题目集里7-4特别的占用时间,繁琐,本来一开始是想着简洁一下代码进行了一部分简单的计算,越算越发现这样的题有点让人烦躁,主要的点还是在计算用表达式和计算值都算不上好的解法,然后同样的代码进行复制修改也更容易产生细节上的错误,所以按我来说,对于7-8来说更不想遇见7-4这样的题目;
2.但是这个7-8当时也没有很好的发挥,当时就是因为根号输入为double类型后与原数有差距,导致判断直角三角形时必须为其增加一个容错量,一开始一直错的时候看了好几遍也不知道哪里出了问题,后面终于发现是这个原因后,只能说是初见杀吧,以后再遇见这样的题目一定会小心谨慎;
3.第二次题目集就题量和难度都蛮适中的,后面几道题循序渐进做起来也确实流畅许多,要说什么踩坑心得那就是if-else太多导致复杂度居高不下,自己没能进行一点改进吧;
4.第三次除了最后一题,前两道难度中等偏下,最后一道完全是一己之力把这次题目集带到了不属于它的高度(bushi,总之不排除难度高一些的题目,但是还是希望难度是慢慢上升的,如果最后一题前也能有一些正则相关的题目引导一下思路,也许更好一点,不过总的来说还是个人拖延畏难的问题。
改进建议:
就是希望很难或者需要自学内容的题目都能进行一个由易到难的引导,这样也能让同学对于做题学习的热情上升,也能保证题目的完成率,除此之外,其他的都挺好的,没有什么别的建议了。
总结:
对于本阶段三次题目集的学习,还是学到了很多东西,从第一次细数的话,对于java的语法更熟悉了;对于上课学到的内容更了解也投入实践了;对于封装的优点也切实体会到了;自己进行了正则表达式的学习,也有一些简单题目的练习;知道不应该先给自己留好退路,不然就没什么做题动力了之类的,总之切实地学习到了很多东西,对于面向对象程序设计这门课的兴趣提高了,之后应该会在遇到正则这样的题目的时候更加得心应手点,也可能是再去学一遍什么的,代码能力确实是需要自己梳理编写才能得到切实的提高,会进行一些额外的题目的练习来巩固。对于课程工作的建议上面也写到了,其他地方应该没有别的建议了,感觉现在的课上氛围和课下的练习检查以及作业什么的都挺好的。