Java题目集1-3总结
学习java快一个月了,题目集也做了3个了,记录一下这一个月Java学习的收获。第一次写这么长的博客>-<.
一.前言
这段时间的java学习共有3次题目集
题目集一较为简单,题量多,主要考察java语句的输入输出,if语句的使用,switch语句的使用,一维数组的定义及使用,循环语句的使用及简单的排序算法。
题目集二题量较第一次少,但难度明显提高,考察了字符串的截取,方法的构造和参数的调用。
题目集三只有3道题,题目难度也明显上升了一个层次,主要考察了类的创建和调用,正则表达式的使用。
二 .题目分析及设计
(1)题目集一:7-8 判断三角形类型
题目描述:输入三角形三条边,判断该三角形为什么类型的三角形。
题目分析:输入三条边,需先判断是否可以构成三角形再进行判断是什么类型的三角形。
代码设计:利用if语句进行多重判断
1 if ( a<1||a>200 || b<1||b>200 || c<1||c>200 ) System.out.println("Wrong Format"); 2 else { 3 if ( a+b<=c || a+c<=b || b+c<=a ) System.out.println("Not a triangle"); 4 else if( a==b&&Math.abs(a*a+b*b-c*c)<0.0001 || b==c&&Math.abs(c*c+b*b-a*a)<0.0001 || a==c&&Math.abs(c*c+a*a-b*b)<0.0001 ) System.out.println("Isosceles right-angled triangle"); 5 else if( a==b && b==c && a==c ) System.out.println("Equilateral triangle"); 6 else if( a==b&&a!=c&&a*a+b*b!=c*c || b==c&&a!=c&&c*c+b*b!=a*a || a==c&&b!=c&&c*c+a*a!=b*b ) System.out.println("Isosceles triangle"); 7 else if( a!=b&&Math.abs(a*a+b*b-c*c)<0.0001 || b!=c&&Math.abs(c*c+b*b-a*a)<0.0001 || a!=c&&Math.abs(c*c+a*a-b*b)<0.0001 ) System.out.println("Right-angled triangle"); 8 else System.out.println("General triangle"); 9 }
最开始写忘记直角三角形的判断不能直接用两边平方等于第三边,应约等于零。所以第四行是
a*a+b*b-c*c<0.0001,而不是a*a+b*b-c*c=0。
这道题目还是很简单的,简单的判断语句和输出语句。
(2)题目集二:7-2 合并两个有序数组为新的有序数组
题目描述:合并两个升序排序的整型数组为一个新的升序整型数组并输出。
题目分析:进行排序。
代码设计:利用 System.arraycopy()。操作很简单,只需要定义两个一维数组并使用 System.arraycopy()合并两个数组再利用Arrays.sort()对合并后的数组进行排序。因为Arrays.sort()是升序排序正符合题目,如果想要降序数组只需利用一个for循环即可完成。
(3)题目集二:7-4 求下一天
题目描述:输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法。
题目分析:判断下一天的日期,需要注意闰年平年2月末和每年每月的最后一天。
代码设计:根据题目要求构造以下方法,进行相应的操作即可。
1 public static void main(String[] args);//主方法 2 public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型 3 public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值 4 public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
public static boolean isLeapYear(int year) { if( year % 400 == 0 || year % 4 == 0 && year % 100 != 0 ) return true; else return false; }
public static boolean checkInputValidity(int year,int month,int day) { if (year<1820||year>2020 || month<1||month>12 || day<1||day>31) return false; else if( isLeapYear(year) == false && month==2 && day>28 ) return false; else if( isLeapYear(year) && month==2 && day>29 ) return false; else if( ( month==4 || month==6|| month==9 || month == 11 ) && day>30 ) return false; else return true; }
1 public static void nextDate(int year,int month,int day) { 2 if( ( month==4 || month==6 || month==9 || month == 11 ) && day==30 ) 3 { month = month + 1 ; day = 1 ; } 4 else if( ( month==1 || month==3 || month==5 || month == 7 || month == 8 || month == 10 ) && day==31 ) 5 { month = month + 1 ; day = 1 ; } 6 else if(month == 12 && day == 31 ) 7 { year = year + 1 ; month = 1 ; day = 1 ; } 8 else if(isLeapYear(year) == false && month==2 && day==28 ) 9 { month = month + 1 ; day = 1 ; } 10 else if(isLeapYear(year) && month==2 && day==29 ) 11 { month = month + 1 ; day = 1 ; } 12 else 13 { day = day + 1 ; } 14 15 System.out.println( "Next date is:" + year + "-" + month + "-" + day ) ; 16 } 17
用了多个if else 所以此次代码圈复杂度非常大
public static void nextDate(int year,int month,int day) 可不用if语句而用switch语句从而降低圈复杂度。此题代码设计较为机械匹配到月末即月份加1,除此之外没有想到更好的操作。
(5)题目集二:7-5 求前N天
题目描述:输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。注意:不允许使用Java中任何与日期有关的类或方法。
题目分析:判断前几天,注意跨月份,跨年。
代码设计:同7-4,没有什么技术要求,依旧是机械的if判断
1 public static void nextDate(int year,int month,int day,int n) { 2 if( ( month==4 || month==6 || month==9 || month == 11 ) && n < 0 ) 3 { month = month + (day + Math.abs(n) ) / 30 ; day = (day + Math.abs(n) ) % 30 ; } 4 5 else if( ( month==1 || month==3 || month==5 || month == 7 || month == 8 || month == 10 ) && n < 0) 6 { month = month + (day + Math.abs(n) ) / 31 ; day = (day + Math.abs(n) ) % 31 ; } 7 8 else if(month == 12 && Math.abs(n) + day > 31 && n < 0 ) 9 { year = year + (day - n ) / 31 ; month = 1 ; day = (day - n ) % 31 ; } 10 11 else if(month == 12 && Math.abs(n) + day < 31 && n < 0 ) 12 { day = Math.abs(n) + day ; } 13 14 else if(isLeapYear(year) == false && month==2 && n < 0 ) 15 { month = month + (day + Math.abs(n) ) / 28 ; day = (day + Math.abs(n) ) % 28 ; } 16 17 else if(isLeapYear(year) && month==2 && n < 0 ) 18 { month = month + (day + Math.abs(n) ) / 29 ; day = (day + Math.abs(n) ) % 29 ; } 19 20 else if( ( month==4 || month==6 || month==9 || month == 8 || month == 11 ) && n > 0 ) 21 { month = month - 1 + (day - n + 31 ) / 31 ; day = (day - n + 31 ) % 31 ; } 22 23 else if( ( month==5 || month == 7 || month == 10 || month == 12 ) && n > 0) 24 { month = month - 1 + (day - n + 30 ) / 30 ; day = (day - n + 30 ) % 30 ; } 25 26 else if( month==1 && n < day ) 27 { day = day - n ; } 28 29 else if( month==1 && n > day ) 30 { year = year - 1 ; month = 12 ; day = (day - n + 31 ) % 31 ; } 31 32 else if(isLeapYear(year) == false && month==3 && n > 0 ) 33 { month = month - 1 + (day - n + 28 ) / 28 ; day = (day - n + 28 ) % 28 ; } 34 35 else if(isLeapYear(year) && month==3 && n > 0 ) 36 { month = month - 1 + (day - n + 29 ) / 29 ; day = (day - n + 29 ) % 29 ; } 37 38 else 39 { } 40 41 System.out.println( n +" days ago is:" + year + "-" + month + "-" + day ) ; 42 }
(5)题目集三:7-2 定义日期类
题目描述:定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
题目分析:判断前几天,注意跨月份,跨年。
代码设计:应题目要求,使用了类,本以为与题目集二 7-4 一样只是多了一个date类,但经老师提醒后发现忽略了java的封装性,不能如题目集二 7-4 一样简单的传参,应利用setter,getter。

理解后类的封装性后就很好操作了。
(6)题目集三:7-3 一元多项式求导(类设计)
题目描述:一元多项式求导
题目分析:进行求导操作,注意正负号,常数求导为0。
代码设计:利用正则表达式判断输入合法性,再进行切割将每一项切割出,接着用两个数组将每一项的系数和指数分别存储起来进行求导操作,最后输出即可完成题目。
1 String str = scan.nextLine(); 2 String common = ".*x+[^0].*x"; 3 String Wrong = ".*[0].*"; 4 String xishu = "[1-9]+"; 5 boolean commonright = str.matches(common); 6 boolean Wrongright = str.matches(Wrong); 7 boolean xishuright = str.matches(xishu); 8 9 if (commonright ) 10 System.out.println(str); //正常测试 11 12 if (Wrongright ) 13 System.out.println("Wrong Format"); //正常测试 14 15 if ( xishuright ) 16 System.out.println("0" ); //常数 17
但惭愧的是卡在了利用数组存储系数和指数这里,一直在想是否可以利用正则表达式直接进行求导操作,结果是没有想出来且数组存储也没做出来,做题还是不能太浮躁 >-< ! 应该老老实实!!!
三.采坑心得
(1)next() 和 nextLine()的区别
发现这两个的区别是在做题目集二ip地址转换是发现区别的,本以为二者读取内容是同样的,但使用next()读取始终有一个测试点未过,换成nextLine()后通过,原
因是非法数据含空格输入用next无法读取到空格,无法检测非法输入。
通过两个简单的测试后可发现next()读取遇到空格即停止读取,而nextLine()读取空格,
查询后得知
• next()方法在读取内容时,会过滤掉有效字符前面的无效字符,对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其过滤掉;只有在读取到有效字符之后,next()方法才将其后的空格键、Tab键或Enter键等视为结束符;所以next()方法不能得到带空格的字符串。
• nextLine()方法字面上有扫描一整行的意思,它的结束符只能是Enter键,即nextLine()方法返回的是Enter键之前没有被读取的所有字符,它是可以得到带空格的字符串的。
所以平时做题需要注意这两者的区别,非常容易忽视的错误,一次课堂作业因为next()和nextLine()的原因eclipse疯狂报错,后来发现只是next与nextLine的问题真的吐血!!! 当时的代码忘记保存了!!!保存错误代码还是很有必要的!!!避免以后犯同样的错误!!!
四.改进建议
(1)代码过于冗长,无注释
1 public static void nextDate(int year,int month,int day,int n) { 2 if( ( month==4 || month==6 || month==9 || month == 11 ) && n < 0 ) 3 { month = month + (day + Math.abs(n) ) / 30 ; day = (day + Math.abs(n) ) % 30 ; } 4 5 else if( ( month==1 || month==3 || month==5 || month == 7 || month == 8 || month == 10 ) && n < 0) 6 { month = month + (day + Math.abs(n) ) / 31 ; day = (day + Math.abs(n) ) % 31 ; } 7 8 else if(month == 12 && Math.abs(n) + day > 31 && n < 0 ) 9 { year = year + (day - n ) / 31 ; month = 1 ; day = (day - n ) % 31 ; } 10 11 else if(month == 12 && Math.abs(n) + day < 31 && n < 0 ) 12 { day = Math.abs(n) + day ; } 13 14 else if(isLeapYear(year) == false && month==2 && n < 0 ) 15 { month = month + (day + Math.abs(n) ) / 28 ; day = (day + Math.abs(n) ) % 28 ; } 16 17 else if(isLeapYear(year) && month==2 && n < 0 ) 18 { month = month + (day + Math.abs(n) ) / 29 ; day = (day + Math.abs(n) ) % 29 ; } 19 20 else if( ( month==4 || month==6 || month==9 || month == 8 || month == 11 ) && n > 0 ) 21 { month = month - 1 + (day - n + 31 ) / 31 ; day = (day - n + 31 ) % 31 ; } 22 23 else if( ( month==5 || month == 7 || month == 10 || month == 12 ) && n > 0) 24 { month = month - 1 + (day - n + 30 ) / 30 ; day = (day - n + 30 ) % 30 ; } 25 26 else if( month==1 && n < day ) 27 { day = day - n ; } 28 29 else if( month==1 && n > day ) 30 { year = year - 1 ; month = 12 ; day = (day - n + 31 ) % 31 ; } 31 32 else if(isLeapYear(year) == false && month==3 && n > 0 ) 33 { month = month - 1 + (day - n + 28 ) / 28 ; day = (day - n + 28 ) % 28 ; } 34 35 else if(isLeapYear(year) && month==3 && n > 0 ) 36 { month = month - 1 + (day - n + 29 ) / 29 ; day = (day - n + 29 ) % 29 ; } 37 38 else 39 { } 40 41 System.out.println( n +" days ago is:" + year + "-" + month + "-" + day ) ; 42 }
当时写的时候可能没有思考清楚,直接上手敲代码,虽然代码能通过正常测试,但再次看自己写的代码时只感觉烦躁,没有注释看起来也略微费劲
加上必要的注释写起来思路也会更清晰。
1 public static String randomName() {//随机人名 2 String name; 3 char[] nameChar; 4 int nameLength=(int)(Math.random()*(5+3)); 5 nameChar=new char[nameLength]; 6 //生成大写首字母 7 nameChar[0]=(char) (Math.random()*26+65); // A的ASCII码65 8 for(int i=1;i<nameLength;i++) { 9 nameChar[i]=(char)(Math.random()*26+97); 10 } 11 name=new String(nameChar); 12 return name; 13 } 14 15 public static long randomID(){ //产生随机ID 16 17 long Id = (int)(Math.random()*(30)) + 13201100; // 第一名同学学号 13201100 18 return Id ; 19 }
后面做题都加上了注释思路看起来更清晰了。
五.总结
第一次题目集开启了我对java的基本认识,java基本的输入输出,判断语句和循环语句和C语言差不多,所以在有了C语言的基础后上手java还是容易的,但想要深入了解还是要多看教材,多掌握知识。
三次题目集下来懂得了java中类的使用,构造方法的使用,刚开始总是搞不明白类是何物,将类和构造方法混淆,上课时总是一脸懵逼,后来发现是因为我没有看mooc上的教学视频,也没有看教材,什么也不懂去听课当然什么也不懂,书是个好东西,得要多看。不断的学习才会不断的进步,正则表达式的学习真的让我全程昏头昏脑,看完一个小时教学视频后自己上手错误百出,总是无法匹配自己想要的表达式,后来沉下心自己一个一个测试基本正则表达式的用法才掌握了一点正则表达式的使用,但题目集三7-3还是没有写出来,怎么说呢,感觉自己真的很菜,同学都能写出来的题目自己写不出来,挺挫败的。这一阶段的学习不仅仅让我学习了java相关的知识,还调整我的学习态度,先学再玩远比先玩再学快乐,做完题后的成就感远比游戏一时胜利的成就感更满足。
进一个月的java学习,知识是学了:方法的构建,类的定义,正则表达式的使用。但感觉还是不能很熟练的应用,接下来的学习对于这些知识点的运用要求肯定更高,在接下来的学习中会更近一步的掌握这些知识点。

浙公网安备 33010602011771号