(1)前言
这是本人学习Java的第一次题目总结的作业,题目集1-3也没有做得多好,但是题目集1-3的大概内容我还是略知一二的。题目集1的主要知识点是Java最最基本的东西,像一些数据用四则运算处理、用if语句完成一些数字语字母的转换、用if else链来完成计算税率问题、一维数组、排序问题、判断三角形类型;题目集2的主要知识点有二进制与十进制的转换、合并两个数组并排序、判断闰年以及求某一天的下一天,前n天;题目集3的主要知识点有私有属性的创建、构造方法、this的用法以及正则表达式。
这三次题目集的题量是线性减少的,但是我认为题目难度是指数增加的(仅仅是个人认为);
(2)设计与分析
这部分是对源码进行分析,由于大部分题目还是挺简单的,所以这里只分析题目集1的7-8,题目集2的7-4、7-5以及题目集3的7-2、7-3。
题目集1的7-8:
题目详情:7-8 判断三角形类型 (20 分)
输入三角形三条边,判断该三角形为什么类型的三角形。
输入格式:
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[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.Scanner;我们才可以输入三条边,我们可以创建一个可以判断三条边是否均合法的方法,最好是返回布尔值的,然后将三条边按照从大到小的顺序排好,先判断三边是否能够构成一个三角形,然后就到了最核心的算法了,其实也就是一系列的if else,什么a*a+b*b=c*c就是直角三角形,a=b&&a=c就是等边三角形……如果不是这些特殊三角形,那就是一般三角形咯;你以为这就完了吗?写完之后你会发现你得不到满分,我怀疑题目给的测试点里面的数有根号,所以要把a*a+b*b=c*c改成a*a+b*b-c*c<=0.00001;
题目集2的7-4:
题目详情:7-4 求下一天 (30 分)
输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法。
要求:Main类中必须含有如下方法,签名如下:
publicstatic
void
main(
String[] args)
;
//主方法
publicstatic
boolean
isLeapYear(
intyear
) ;
//判断year是否为闰年,返回boolean类型
publicstatic
boolean
checkInputValidity(
intyear
,
intmonth
,
intday
);
//判断输入日期是否合法,返回布尔值
publicstatic
void
nextDate(
intyear
,
intmonth
,
intday
) ;
//求输入日期的下一天
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
1. 当输入数据非法及输入日期不存在时,输出“Wrong Format”;
2. 当输入日期合法,输出下一天,格式如下:Next date is:年-月-日
这题是给你一个日期让你求下一天,首先要判断该年是否是闰年,通过这个方法public static boolean isLeapYear(int year)来判断,就可以得出2月份的天数,然后判断给出的日子是否合法,通过public static boolean checkInputValidity(int year,int month,int day)该方法来判断,然后就是最核心的部分,求下一天,
int[]a=newint[]{31,28,31,30,31,30,31,31,30,31,30,31}; if(isLeapYear(year))
a[1]=29;
通过这部分就可以得到任何一个月的天数,然后就是挖出一些特殊情况:一、当月份为12,如果天数刚好是该月的最后一天,那么年份加1,月和日都变为1,否则只需将日加1;二、当月份在0-12之间,如果天数是当月的最后一天,则月加1,日变为1,否则日加1。
这题刚写的时候可能会无从下手,但是慢慢理解,把逻辑捋顺之后还是很容易理解的。
题目集2的7-5:
7-5 求前N天 (30 分)
输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。
输入格式:
在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。
输出格式:
- 当输入的年、月、日以及n的值非法时,输出“Wrong Format”;
- 当输入数据合法时,输出“n days ago is:年-月-日”
这题跟题目集2的7-4类似,也是先用public static boolean isLeapYear(int year)来判断输入的年份是否合法,如果合法,就先挖出几个特殊的地方,(day - n >= 1 && day - n <= M[month])、(day - n < 1)、(month - 1 < 1)、(month+1>12)。总之你会做求下一天就会做求前n天。
题目集3的7-2:
题目详情:定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
好吧,这道题又是跟日期有关,但不同的是题目给了我们一个uml类图,也就是先给了我们这个程序的一个大致的框架,我们只需要补好代码就行,
这题依然是有一个public static boolean isLeapYear(int year)判断闰年,public static boolean checkInputValidity(int year,int month,int day)检查日期合法性,跟前面不同的是这题可以更好地体现类的封装。
题目集3的7-3:
7-3 一元多项式求导(类设计) (50 分)
编写程序性,实现对简单多项式的导函数进行求解。详见作业指导书。 OO作业3-3题目说明.pdf
输入格式:
在一行内输入一个待计算导函数的表达式,以回车符结束。
输出格式:
- 如果输入表达式不符合上述表达式基本规则,则输出“Wrong Format”。
- 如果输入合法,则在一行内正常输出该表达式的导函数,注意以下几点: 结果不需要排序,也不需要化简;
- 当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
- 当输出结果第一项系数符号为“+”时,不输出“+”;
- 当指数符号为“+”时,不输出“+”;
- 当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可。
这题毫无疑问是这三次作业的大boss了,一元多项式求导,放在数学里面人人都会,可是在这里可就难了,因为他要用到我们之前没有听过的正则表达式,直接上代码吧,下面这部分代码可以识别大于2的整数
public static void main(String[] args) { String regex = "([2-9]+[0-9]*)|([1-9]+[0-9]+)"; String input="1"; Pattern pattern = Pattern.compile(regex); boolean bl=Pattern.matches(regex, input); if(bl==true) { Matcher matcher=pattern.matcher(input); while(matcher.find()) { String tmp=matcher.group(); int begin=matcher.start(); int end=matcher.end(); System.out.println("项:"+tmp+" begin:"+begin+" end:"+ (end-1)); if(end==input.length()) break; } } else System.out.println("not matched"); }
String totalRegex = "([-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[0-9]+)?)+"; String sbuRegex = "[-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[0-9]+)?"; String input="x^-5+6*x^7-1200*x^-1000+54468799958488*x^-925546"; input="-2*x^-2+5*x^12-4*x+12"; //input="2*x^6-0*x^7+5"; boolean bl=Pattern.matches(totalRegex, input); if(bl==true) { Pattern pattern = Pattern.compile(sbuRegex); Matcher matcher=pattern.matcher(input); while(matcher.find()) { String tmp=matcher.group(); int begin=matcher.start(); int end=matcher.end(); System.out.println("项:"+tmp+" begin:"+begin+" end:"+ (end-1)); if(end==input.length()) break; } } else System.out.println("Wrong Format");
(3)踩坑心得
众所周知,就算是资深程序员也难免会犯一些小错误,我们在做题目的时候也难免会踩到一些坑,下面我来列出一些我所踩到的坑:
1、不知道pta只能写public class Main,第一题的时候没有用这个Main,导致一直提交,一直编译错误。
2、 没有构造方法,什么东西都往public static void main(String[] args)里面, 这就导致一些逻辑错误难以被发现,就像这样:
特别是这种if else还特别多的程序,非常容易对错了,而且非常难找错误,最后实在找不出问题的话,可能要重新写过程序,这就非常难受了,还大大地降低了我们的效率。所以要把总的功能不断分割成一个个小功能,分的越多程序越好找问题。
3、 不知道pta里面的测试点会给你什么类型的数据,就像题目集1的最后一题,就是求三角形的类型,在判断直角三角形的那一部分,一般人都会想到用a*a+b*b=c*c,但是你用这个就是得不到满分,好像是因为题目给你的测试点里面有根号。要改成a*a+ b*b-c*c<0.00001或者其他的才能对。
(4)改进建议
题目的跨越有点大,可以多设一些中等题目来衔接这些简单和超难题目,这样更容易让大部分学生接受。
(5)总结
总的来说,这三次题目集还是令我收获很多的,从一开始只会输入输出的我,到后面学习了Java对象和类、循环结构、条件语句、以及正则表达式、Java封装、Java方法,最重要的是这几次作业让我有了一定的面向对象编程的思想,这是我学习Java过程中第一次迈开的一小步,但是有些知识点还是不熟练,像正则表达式,这次的求导是最基本的函数,后面还有更复杂的函数,所以本菜鸟还需要进一步学习正则表达式。