三次作业总结博客
l 前言
- 第一次题目集是我刚刚接触java所做的第一套习题,本次题目难度不大,题量较多,涉及的知识点主要是基础的语法知识,出题人的意图是让我们尽快熟悉java的语法,由于事先有c语言学习的基础,其与java二者之间有着诸多的相似之处,对于java的语法学习也是顺风顺水,第一次轻松拿下。
- 到了第二次题目集的时候,前三道题目还是老样子,对java基础语法的考察,后面两道题目增添了需要我们进行类的封装,而不是单单地写一个Main类,这也是我们面向对象编程的起步,难度中等。
- 第三次难度一下子上来了,先是设计题目中需求的类,然后是对类的各种操作,创建,引用等,最后是对正则表达的运用,难度对我来说偏大,写起来没有前两次那么容易,废了好大功夫才搞定。
l 设计与分析
第一次题目集
输入三角形三条边,判断该三角形为什么类型的三角形。
输入格式:
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[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”。
源代码如下:
import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); double a = input.nextDouble(); double b = input.nextDouble(); double c = input.nextDouble(); if((a>=1&&a<=200)&&(b>=1&&b<=200)&&(c>=1&&c<=200)) { if(a+b>c&&a+c>b&&b+c>a) { if(a==b||a==c||b==c) { if(a==b&&a==c) System.out.print("Equilateral triangle"); else if((a*a+b*b-c*c<0.00001)||(a*a+c*c-b*b<0.00001)||(b*b+c*c-a*a<0.00001)) System.out.print("Isosceles right-angled triangle"); else System.out.print("Isosceles triangle"); } else if((a*a+b*b-c*c<0.00001)||(a*a+c*c-b*b<0.00001)||(b*b+c*c-a*a<0.00001)) System.out.print("Right-angled triangle"); else System.out.print("General triangle"); } else System.out.print("Not a triangle"); } else System.out.print("Wrong Format"); } }
解题思路:
首先思考判定三角形的条件,任意两边之和大于第三边;接下来是等腰三角形,要满足任意两边相等;直角三角形,两边的平方和等于第三边的平方,且同时满足是等腰三角形则为等腰直角三角形;三边都相等则为等边三角形。本题的解决思路就是if判断语句的构建,接下来开始按条件编写代码即可。
样例测试:
输入样例1:
在这里给出一组输入:
50 50 50.0
输出样例1:
在这里给出相应的输出:
Equilateral triangle
输入样例2:
在这里给出一组输入:
60.2 60.2 80.56
输出样例2:
在这里给出相应的输出:
Isosceles triangle
输入样例3:
在这里给出一组输入:
0.5 20.5 80
输出样例3:
在这里给出相应的输出:
Wrong Format
第二次题目集
输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[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:年-月-日
源代码如下:
import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int year=input.nextInt(); int month=input.nextInt(); int day=input.nextInt(); check( year, month , day); nextDate(year,month,day); } public static boolean isLeapYear(int year) { if((year%4==0&&year%100!=0)||year%400==0) return true; else return false; } public static void nextDate(int year,int month,int day) { if(month==4||month==6||month==9||month==11) { if(day==30) { day=1; month++; } else day++; } else if(month==2) { if(isLeapYear(year)) { if(day==29) { month=3; day=1; } else day++; } else { if(day==28) { month=3; day=1; } else day++; } } else { if(day==31) { day=1; if(month==12) { month=1; year++; } else month++; } else day++; } System.out.print("Next date is:"+year+"-"+month+"-"+day); } public static void check(int year,int month ,int day) { if((year<1820||year>2020)||(month<1||month>12)||(day<1||day>31)) { System.out.print("Wrong Format"); System.exit(0); } if(isLeapYear(year)==false) { if(month==2) { if(day==29) { System.out.print("Wrong Format"); System.exit(0); } } } } }
解题思路:
此题为年月日相关的题目,求该日期的下一天,关于日期有很多要考虑的细节,比如闰年和平年二月的区别,还有进入下一年的情况,都要考虑到,要用if语句判断该月有多少天,除去主方法还要设计三个其他方法,分别检查输入,判断闰年,计算出下一天。难度不大,需要细心分析if的条件来编写代码
样例测试:
输入样例1:
在这里给出一组输入:
2020 3 10
输出样例1:
在这里给出相应的输出:
Next date is:2020-3-11
输入样例2:
在这里给出一组输入:
2025 2 10
输出样例2:
在这里给出相应的输出:
Wrong Format
输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。
输入格式:
在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。
输出格式:
- 当输入的年、月、日以及n的值非法时,输出“Wrong Format”;
- 当输入数据合法时,输出“n days ago is:年-月-日”
源代码如下:
import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int year=input.nextInt(); int month=input.nextInt(); int day=input.nextInt(); check( year, month , day); int n=input.nextInt(); theDate(year,month,day,n); } public static boolean isLeapYear(int year) { if((year%4==0&&year%100!=0)||year%400==0) return true; else return false; } public static void check(int year,int month ,int day) { if((year<1820||year>2020)||(month<1||month>12)||(day<1||day>31)) { System.out.print("Wrong Format"); System.exit(0); } if(isLeapYear(year)==false) { if(month==2) { if(day==29) { System.out.print("Wrong Format"); System.exit(0); } } } } public static void theDate(int year,int month,int day,int n) { if(month==4||month==6||month==9||month==11) { if(day-n>0&&day-n<31) { day=day-n; } else if(day-n<1) { month--; day=31+day-n; } else { day=day-n-30; month++; } } else if(month==2) { if(isLeapYear(year)) { if(day-n>29) { month=3; day=day-n-29; } else if(day-n<1) { month--; day=31+day-n; } else day=day-n; } else { if(day-n>28) { month=3; day=day-n-28; } else if(day-n<1) { month--; day=31+day-n; } else day=day-n; } } else { if(day-n>0&&day-n<32) day=day-n; else if(day-n<1) { if(month==1) { year--; month=12; day=31+day-n; } else if(month==8) { month--; day=31+day-n; } else if(month==3) { month--; if(isLeapYear(year)) { day=29+day-n; } else day=28+day-n; } else { month--; day=30+day-n;} } else { if(month==12) { day=day-n-31; month=1; year++; } else {day=day-n-31; month++; } } } System.out.print(n+" days ago is:"+year+"-"+month+"-"+day); } }
解题思路:
此题为年月日相关的题目,求该日期的前几天,有很多要考虑的细节,比如闰年和平年二月的区别,日期可以为负值,如果日期的值为负值那么也就是求该日期的后几天。还有进入下一年和回到上一年的情况,都要考虑到,要用if语句判断该月有多少天,除去主方法还要设计三个其他方法,分别检查输入,判断闰年,计算出前n天。难度不大,需要细心分析if的条件来编写代码,最后注意输出格式。
样例测试:
输入样例1:
在这里给出一组输入:
2018 6 19 8
输出样例1:
在这里给出相应的输出:
8 days ago is:2018-6-11
输入样例2:
在这里给出一组输入:
2018 6 19 -8
输出样例2:
在这里给出相应的输出:
-8 days ago is:2018-6-27
第三次题目集
定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
要求:Date类结构如下图所示:
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
- 当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
- 当输入日期合法,输出下一天,格式如下:Next day is:年-月-日
源代码如下:
import java.util.*; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int year=input.nextInt(); int month=input.nextInt(); int day=input.nextInt(); check( year, month , day); nextDate(year,month,day); } public static boolean isLeapYear(int year) { if((year%4==0&&year%100!=0)||year%400==0) return true; else return false; } public static void nextDate(int year,int month,int day) { if(month==4||month==6||month==9||month==11) { if(day==30) { day=1; month++; } else day++; } else if(month==2) { if(isLeapYear(year)) { if(day==29) { month=3; day=1; } else day++; } else { if(day==28) { month=3; day=1; } else day++; } } else { if(day==31) { day=1; if(month==12) { month=1; year++; } else month++; } else day++; } System.out.print("Next day is:"+year+"-"+month+"-"+day); } public static void check(int year,int month ,int day) { if((year<1900||year>2000)||(month<1||month>12)||(day<1||day>31)) { System.out.print("Date Format is Wrong"); System.exit(0); } if(isLeapYear(year)==false) { if(month==2) { if(day==29) { System.out.print("Date Format is Wrong"); System.exit(0); } } } } }
解题思路:
此题为年月日相关的题目,求该日期的下一天,关于日期有很多要考虑的细节,比如闰年和平年二月的区别,还有进入下一年的情况,都要考虑到,要用if语句判断该月有多少天,除去主方法还要设计三个其他方法,分别检查输入,判断闰年,计算出下一天。难度不大,需要细心分析if的条件来编写代码
样例测试:
输入样例1:
在这里给出一组输入:
1912 12 25
输出样例1:
在这里给出相应的输出:
Next day is:1912-12-26
输入样例2:
在这里给出一组输入:
2001 2 30
输出样例2:
在这里给出相应的输出:
Date Format is Wrong
l 采坑心得
写代码从来都不是一蹴而就的,bug肯定再所难免,在此我来谈谈本次习题除了语法错误还有关于日期的细节之外导致我没有通过测试点的大几个“坑”
- print与println
print主要是继承了C语言的printf的一些特性,可以进行格式化输出
print就是一般的标准输出,但是不换行
println和print基本没什么差别,就是最后会换行
2. input.next();与input.nextLine();读取字符串
next()一定要读取到有效字符后才可以结束输入,对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其去掉,只有在输入有效字符之后,next()方法才将其后输入的空格键、Tab键或Enter键等视为分隔符或结束符。简单地说,next()查找并返回来自此扫描器的下一个完整标记。完整标记的前后是与分隔模式匹配的输入信息,所以next方法不能得到带空格的字符串
而nextLine()方法的结束符只是Enter键,即nextLine()方法返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的
意思就是说,nextInt()读到有效值后就结束,输完数字后按的回车符还存在,nextLine()读取到回车符就直接结束,所以结果就类似于跳过了该条输入语句
3. java数组创建用new与不用new的区别
1、不同于String类,String由于实现了常量池
所以new 和不new 有区别:new的话,引用变量指向堆区。不new的话,引用变量指向常量池。
2、对于数组的定义,初始化时用new与不用new 没区别,只是两种方式罢了,因为数组是引用数据类型,建立对象时,无论用不用new,数组实体都是放在堆内存中,引用变量放在栈内存。int a[] = {1, 2, 3}; 和 int a[] = new int[] {1, 2, 3}; 实际上是等价的。
4.“+”
Java输出需要用到连接符“+”。 java中加号+一般对新手来说,可能不像减号,乘除那样好理解,java中的加号有两个意思,一个是常见的算术运算中的相加的意思,另一个是连接符的作用。
5. 封装思想
所谓封装,就是将属性和方法捆绑到一起,封装到一个对象中去,简单的说,你是人,你有许多属性,比如说你的姓名,年龄,身高,体重,性别,性格,爱好等等,这是属性;而同时,你又会吃饭,睡觉,工作,学习,做事情,这些是方法,是你所具有的;同时将属性和方法封装到一个类中去,就能很完美的描述这个类的特征了,同时,它所具有的方法也就一起集成到类中,方便使用。这些是简单的描述了。
至于什么时候需要这个似乎不是讨论的重点了,既然是java号称完全面向对象的语言,那么,你就应该一直以封装方式去思考问题和设计类了。
l 改进建议
丰富测试样例,使其具有普遍性,以便保证最终提交的程序没有bug
l 总结
通过以上三次的编程练习,打开了我学习java的大门,从此开始进入面向对象编程的道路,第一次的练习对java的基本语法有了熟练地掌握,基本能够编写出没有语法错误的代码,为以后的深入学习打下坚实的基础;通过后两次的实验练习,我对类的定义印象更加深刻了,对类的操作更加熟悉了;面向对象的封装思想就是对类进行处理,只有对类熟练掌握,我们才能学好面向对象编程,提高自己的编程思维,以后的职业生涯能少走弯路,希望以后的学习生涯能顺风顺水!