一、前言
这是我们OO课的第一次作业总结,学习java也将近一个月了,从上学期的C语言转变到现在的java,既有交叉又有改变。从面向过程到面向对象的转折,需要一段时间去适应。教学方式的多元化,学习平台的多样化给我们一个很好地学习环境,但从一次次作业的完成和总结中,我们也能学到很多。下面就是我对于之前pta平台上老师布置的题目集的一些相关题目的总结与梳理。
二、作业总结
1.判断三角形类型(题目集01-7-8)
题目分析:
该题的重点内容就是如何判断三角形的类型,以及判断输入的三边是否能构成三角形。检验的是java的基础语法知识。
对于此题我的第一想法就是使用几个嵌套的if语句分别对三边的合法性,是否存在直角,是否有两条边相等,再分别进一步判断是否为等边三角形或者等腰直角三角形;
实现代码如下:
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*a+b*b-c*c<0.000001||a*a+c*c-b*b<0.000001||c*c+b*b-a*a<0.0000001)//判断是否为直角三角形
{
if(a==b||a==c||c==b)//判断是否为等腰三角形
{
System.out.println("Isosceles right-angled triangle");//等腰直角三角形
}
else
System.out.println("Right-angled triangle");//直角三角形
}
else if(a==b||b==c||c==a)
{
if(a==b&&a==c)//判断是否为等边三角形
System.out.println("Equilateral triangle");//等边三角形
else
System.out.println("Isosceles triangle");//等腰三角形
}
else
System.out.println("General triangle");//普通三角形
}
else
System.out.println("Not a triangle");//无法构成三角形
}
else
System.out.println("Wrong Format");//数据非法
改进与解析:
这样简单通俗易懂,一目了然,但却有一点冗长。思虑过后认为用switch语句更为清爽直接一些
其中有一点要提的是,一开始判断三条边是否成直角的时候判断条件写的是:
a*a+b*b-c*c==0||a*a+c*c-b*b==0||c*c+b*b-a*a==0
比较浮点数是否相等,比较特殊,最好不要用 ==,比如浮点数a和b进行比较,写成if(a ==b)有时也许会出现你不期望出现的情况。
这样损失了一部分精度,导致一些测试点无法通过。最好用比较,例如本题:
a*a+b*b-c*c<0.000001||a*a+c*c-b*b<0.000001||c*c+b*b-a*a<0.0000001
下面是代码的复杂度分析
Metrics Details For File 'Main1.java'
--------------------------------------------------------------------------------------------
Parameter Value
========= =====
Project Directory D:\新建文件夹\Main1\src\
Project Name Main1
Checkpoint Name Baseline
File Name Main1.java
Lines 38
Statements 26
Percent Branch Statements 42.3
Method Call Statements 11
Percent Lines with Comments 0.0
Classes and Interfaces 1
Methods per Class 1.00
Average Statements per Method 23.00
Line Number of Most Complex Method 3
Name of Most Complex Method Main1.main()
Maximum Complexity 23
Line Number of Deepest Block 17
Maximum Block Depth 6
Average Block Depth 3.11
Average Complexity 23.00
--------------------------------------------------------------------------------------------
Most Complex Methods in 1 Class(es): Complexity, Statements, Max Depth, Calls
Main1.main() 23, 23, 6, 11
--------------------------------------------------------------------------------------------
Block Depth Statements
0 2
1 2
2 8
3 3
4 4
5 7
6 1
7 0
8 0
9+ 0
--------------------------------------------------------------------------------------------
2.求下一天(题目集02-7-4)
题目分析:
该题的重点是判断是否为闰年,判断输入日期是否合法,以及求输入日期的下一天,检验的是学会构造一些相关方法,以及方法的调用;
对于此题我的想法是按照题目的要求构造三个相关方法,分别用于判断闰年,判断日期是否合法以及求下一天的日期;
1)判断闰年,且返回布尔类型,判断闰年的条件已经很熟悉了,重点在于构造方法以及返回布尔值,但其实这都很简单,话不多说直接上代码:
public static boolean isLeapYear(int year) //判断year是否为闰年,返回boolean类型 { boolean isLeapYear = (year%4==0&&year%100!=0)||year%400==0; return isLeapYear; }
2)判断输入的日期是否合法,同样返回值也是布尔型,思考了一下,就按照判断闰年的方法试着仿写,并不难,同样上代码:
public static boolean checkInputValidity(int year,int month,int day)//判断输入日期是否合法,返回布尔值 { boolean checkInputValidity = (year>=1820&&year<=2020&&month>0&&month<=12&&day<=s[month]&&day>0); return checkInputValidity; }
3)求输入日期的下一天,也是本题的重点,一开始的主要想法就是先判断数据是否合法,然后判断是否为闰年,然后用if语句分支写出各种情况下的年月日。也是比较简单的,但是一定得注意嵌套的时候的各种条件用,例如2月,12月,各个月的月末都是比较特殊的,应当注意。最后的惯例,上代码:
public static void nextDate(int year,int month,int day) //求输入日期的下一天 { int a=0,b=0,c=0; int s[]=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; if(isLeapYear(year)) s[2]=29; if(checkInputValidity(year,month,day))//判断日期是否合法 { if(month==12) { if(day==s[month])//特殊日期12月月底 { a=year+1; b=1; c=1; } if(day>0&&day<s[month]) { a=year; b=month; c=day+1; } } if(month<12) { if(day==s[month])//各个月的月底 { a=year; b=month+1; c=1; } if(day>0&&day<s[month]) { a=year; b=month; c=day+1; } } System.out.println("Next date is:"+a+"-"+b+"-"+c); } else System.out.println("Wrong Format"); }
4)最后是主函数,比较重要的是学会如何调用相关方法,emmmm,也没啥好说的,还是上代码吧:
public static void main(String[] args)//主方法 { Scanner in = new Scanner(System.in);
int year =in.nextInt(); int month =in.nextInt(); int day =in.nextInt(); yxy.nextDate(year,month,day); }
最后!在 main() 方法中只能直接调用静态方法,如果想调用非静态方法,需要将当前类实例化,然后通过类的对象来调用。就相当于前面代码中的
Main yxy=new Main();
3.求前N天(题目集02-7-5)
题目分析:该题与前一题求下一天其实主要思想差别不大,只是在判断日期的时候应该多加注意,比较于上一道题,这一道的题判断更加繁琐,需要更加细心一些。
对于此题我的想法就是仿造上一题的写法,但在输入时候了解到另一种写法,能够有效的判断一部分输入值是否合法,在下面我也会提起并且稍微讲解一下。因为判断时候合法以及判断是否为闰年的方法与上一题基本一致,这一题就不再提了,重点讲一下求前N天的方法以及Main方法。
1)求前后N天,分为了n大于0,和n小于0的两种情况就可以求前N天和后N天。总体来说,比较简单,甚至比上一题的代码更加简洁。
public static void nextDate(int year,int month,int day,int n) { int[] mm={0,31,28,31,30,31,30,31,31,30,31,30,31}; if (isLeapYear(year))mm[2]=29; day-=n; if (n>0){ while (day<=0){ month--; if (month==0){ month+=12; year--; } day+=mm[month]; } }else if (n<0){ while (day>mm[month]) { day-=mm[month]; month++; if (month==13){ month-=12; year++; } } } System.out.println(n+“ days ago is:"+year+"-"+month+"-"+day); }
2)主方法
这里值得一讲的是使用了方法hasnextInt(),java中hasNextInt方法用来判断下一个输入是否是int型整数,函数原型为 public boolean hasNextInt(); 函数的返回类型是boolean,也就是说如果下一个输入可转换为整数,那就返回true,否则返回false。
public static void main(String[] args) { Scanner in = new Scanner(System.in); boolean x=true; int a=0,b=0,d=0,n=0; if (in.hasNextInt()) a= in.nextInt(); else x=false; if (in.hasNextInt()) b= in.nextInt(); else x=false; if (in.hasNextInt()) d= in.nextInt(); else x=false; if (in.hasNextInt()) n= in.nextInt(); else x=false; if (checkInputValidity(a,b,d,n)&&x){ nextDate(a,b,d,n); }else System.out.println("Wrong Format"); } public static boolean isLeapYear(int year) { boolean ret=false; if ((year%100!=0&&year%4==0)||(year%400==0)){ ret=true; } return ret; }
4.定义日期类(题目集03-7-2)
题目分析:该题一上一题目集的7-4是一样的,不过这里要求定义一个日期类,需要自己定义一些方法,主要方法的构架如下图:![]()
同时,该题还有一些要求要求,必须保证类的封装性
(1)year、month、day等属性必须是私有成员
(2)类中的方法,必须针对类的year、month和day进行操作,而不是简单的题目集2中的写法。
这在C语言当中就相当于定义一些函数,然后在主函数当中调用了,这样使得主方法比较简单明了,而且即用即调,更加利于代码的编写。这题的要求当中,创建了一些无参构造方法,以及getter及setter方法
封装数据,对私有属性进行封装,即只是暴露出public方法来访问。但是为什么要这么做呢?封装的作用就是保护,保护属性本身不被篡改。比如有些属性只是可读但不可写,那么只提供它的getter方法就好,意思就是某些属性只能单一方向的被访问,getter和setter就是提供这样的接口,对于public的属性,可以直接使用类名来访问,自身的“安全性”就降低了。
具体的代码如下:
private int year;//年 int month;//月 private int day;//日 private int id;//账号 private double balance;//余额 private double annuallnterestRate;//当前利率 private Date dateCreated; public Date(){//无参函数 } public Date(int year,int month,int day)//获得年月日 { this.year=year; this.month=month; this.day=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; }
至于其他方法构造与上一题基本的想法一样,所以就不再附上代码了,也不再做解释了。
另外,对于getter和setter这两个方法查了一些资料,归纳如下:
setter方法
1.可以限制和检验setter方法传入的参数
2.隐藏对象内部数据结构
3.保持对象在每个状态的完整性
getter方法
1.按照客户的期望返回格式化数据
2.控制服务的顺序(例如只有当连接建立时getter方法才返回相应实例)
5.一元多项式求导(类设计)(题目集03-7-3)
题目分析:这一题的难度对我来说很大,现在也没能搞定一些方法和思想的实现,看到这道题的时候,我整个人都是懵的,第一次看到这么长的题,经过我仔细分析和琢磨之后,主要的想法就是去空格,分割,匹配,求导,但看起来简单,实际实现起来比较困难。最好的方法就是使用正则表达式,但因为我才疏学浅,不能很好地应用,就按照老师9给的提示写了一段,但还是有所缺欠,这里就不放代码出来了,等完全写出来了之后再说吧。
对于去空格只需要用一个replace的方法将字符串里的空格替换为空就行。例如:
String thee=in.nextLine();
String thee1=thee.replace(" ","");//删去所有空格
对于常量的想法是首先先排查该项中是否含有’x‘,如果不含则该项为零,当一整个多项式都为常数时输出0,如果仅为一项,则该项为null。
正则表达式是用一个字符串来验证一类字符串,查找字符串,替换等;不是很会,就讲一些我知道的。
Matches()当且仅当正则匹配整个字符串时,,split(),replaceFirst(),replaceALL()
Group()返回匹配结果
三、体会与想法
一开始以为java跟c语言应该差别不大,或者说学了C语言在学java应该会很简单,但没想到的是,java远比我想想中的难得多,也是因为学过C语言的缘故,java的进程很快,而且,一开始在写代码的时候,总是用写C语言的思想来写,以至于有时候忽略了很多细节,比如构造一个对象啊定义一个结构体啊什么的,再者,java语言与c语言在写法上有较大的改变,应该加紧习惯起来。一些方法啊什么的都需要我们通过多写一些实例题去发现去了解,比如这次的正则表达式。
(System.out.println("一学java深似海"));
四、相关资料
1、Getter和Setter方法作用https://blog.csdn.net/Jason_LH1024/article/details/90900339
2、多项式 正则表达式参考http://www.bubuko.com/infodetail-2360245.html
3、sourcemonitor使用方法https://blog.csdn.net/qq_34400736/article/details/53464738

浙公网安备 33010602011771号