目录
1. 前言
2.代码分析
3.三次作业遇到的bug及采坑心得
4.改进建议
5.总结
一、前言
这学期开始接触java,面向对象以前也只是在c++学过一点,所以一开始对于写这次blug有点手足无措,不过还好学会了SourceMonitor软件的使用,对于我分析代码提供了很大的帮助。
下面是我对三次题目集的大体分析:
题目集1
题量:8道
知识点:java的简单运用:顺序结构、选择结构、循环结构,数组的建立等
难度:只要有别的语言基础如c、c++等,难度偏易
题目集2
题量:5道
知识点:字符串的运用,java中方法的引用
难度:一般
题目集3
题量:3道
知识点:对象和类,java中类的封装性,正则表达式的运用
难度:前两题难度一般,最后一题较难
二、代码分析
由于学校要求,本次代码分析就分析题目集中的重点题目即题目集1的7-8,题目集2的7-4、7-5以及题目集3的7-2、7-3。
题目集1
7-8
该题代码如下:
import java.util.*; import java.lang.*; public class Main{ public static void main(String[] args){ Scanner in = new Scanner(System.in); double [] arr = new double[3]; for(int i=0;i<arr.length;i++){ arr[i]=in.nextDouble(); } Arrays.sort(arr,0,3); if(arr[0]<1||arr[0]>200||arr[1]<1||arr[1]>200||arr[2]<1||arr[2]>200) { System.out.println("Wrong Format"); } else { if((arr[0]+arr[1])>arr[2]) { if(Math.abs(arr[2]*arr[2]-arr[0]*arr[0]-arr[1]*arr[1])<0.1) { if((arr[0]==arr[1]&&arr[0]!=arr[2])||(arr[0]==arr[2]&&arr[1]!=arr[2])||(arr[1]==arr[2]&&arr[0]!=arr[2])) { System.out.println("Isosceles right-angled triangle"); } else { System.out.println("Right-angled triangle"); } } else if(arr[0]==arr[1]&&arr[1]==arr[2]&&arr[0]==arr[2]) { System.out.println("Equilateral triangle"); } else if((arr[0]==arr[1]&&arr[0]!=arr[2])||(arr[0]==arr[2]&&arr[0]!=arr[1])||(arr[1]==arr[2]&&arr[0]!=arr[2])) { System.out.println("Isosceles triangle"); } else { System.out.println("General triangle"); } } else { System.out.println("Not a triangle"); } } } }
度量:
分析:这第一次作业比较简单,只要用if条件句找到就输出就基本可以拿到分了,但经过分析发现块的深度有点高,下次一定得改正。
题目集2
这次的作业因为要调用类中的方法所以整体难度比第一次作业要高,与c中函数的调用很像。
7-4
该题代码如下:
import java.util.Scanner; public class Main { public static boolean isLeapYear(int year) { if(year%4==0&&year%100!=0) return true; else if(year%400==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<=12&&month>=1&&day>=1&&day<=31){ if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ if(day<=31&&day>=1){ return true; } else{ return false; } } else if(month==4||month==6||month==9||month==11){ if(day<=30&&day>=1){ return true; } else{ return false;} } else if(month==2){ if(isLeapYear(year)){ if(day<=29&&day>=1){ return true; } else{ return false; } } else{ if(day<=28&&day>=1){ return true; } else{ return false; } } } } return false; } public static void nextDate(int year,int month,int day){ if(month==1||month==3||month==5||month==7||month==8||month==10){ if(day<31){ day++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } else{ day=1; month++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } } else if(month==4||month==6||month==9||month==11){ if(day<30){ day++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } else{ day=1; month++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } } else if(month==2){ if(isLeapYear(year)){ if(day<29){ day++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } else{ day=1; month++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } } else{ if(day<28){ day++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } else{ day=1; month++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } } } else if(month==12){ if(day<31){ day++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } else{ day=1; month=1; year++; System.out.println("Next date is:"+year+"-"+month+"-"+day); } } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int year =in.nextInt(); int month=in.nextInt(); int day=in.nextInt(); if(checkInputValidity(year,month,day)) { nextDate(year,month,day); } else { System.out.println("Wrong Format"); } } }
度量:
分析:这道题因为方法设置的有点多,所以导致方法平均语句有点高甚至超过了题目设置的代码长度限制,后来改了下代码风格就没问题了。
7-5
该题代码如下:
import java.util.Scanner; public class Main { public static boolean isLeapYear(int year) { if(year%4==0&&year%100!=0) return true; else if(year%400==0&&year%100==0) return true; else return false; } public static boolean checkInputValidity(int year,int month,int day,int n) { if(year>=1820&&year<=2020&&month<=12&&month>=1&&day>=1&&day<=31&&n<=10&&n>=-10) { if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) { if(day<=31&&day>=1) { return true; } else { return false; } } else if(month==4||month==6||month==9||month==11) { if(day<=30&&day>=1) { return true; } else { return false; } } else if(month==2) { if(isLeapYear(year)) { if(day<=29&&day>1) { return true; } else { return false; } } else { if(day<=28&&day>=1) { return true; } else { return false; } } } } return false; } public static void lastDate(int year,int month,int day,int n) { if(n>0) { if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) { if(day-n>=1) { day=day-n; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else { if(month==3) { if(isLeapYear(year)) { month--; day=29-Math.abs(day-n); System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else { month--; day=28-Math.abs(day-n); System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } } else if(month==1) { year--; month=12; day=31-Math.abs(day-n); System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else if(month==8) { month--; day=31-Math.abs(day-n); System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else { month--; day=30-Math.abs(day-n); System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } } } else if(month==4||month==6||month==9||month==11||month==2) { if(day-n>=1) { day=day-n; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else { month--; day=31-Math.abs(day-n); System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } } } else if(n<0) { if(month==1||month==3||month==5||month==7||month==8||month==10) { if(day-n<=31) { day=day-n; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else { month++; day=day-n-31; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } } else if(month==12) { if(day-n<=31) { day=day-n; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else { year++; month=1; day=day-n-31; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } } else if(month==2) { if(isLeapYear(year)) { if(day-n<=29) { day=day-n; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else { day=day-n-29; month++; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } } else { if(day-n<=28) { day=day-n; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else { day=day-n-28; month++; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } } } else if(month==4||month==6||month==9||month==11) { if(day-n<=30) { day=day-n; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } else { month++; day=day-n-30; System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } } } else if(n==0) { System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int year =in.nextInt(); int month=in.nextInt(); int day=in.nextInt(); int n=in.nextInt(); if(checkInputValidity(year,month,day,n)) { lastDate(year,month,day,n); } else { System.out.println("Wrong Format"); } } }
度量:
分析:这道题有部分方法与7-4题中方法一样,但lastDate方法因为判断情况过多所以较长,导致代码块平均深度较大。
题目集3
第三次作业前两道题比第两次作业中的题多了对于数据域封装性的运用和对与外部类的调用还有对于封装的理解,并没有别的对于我来说而第三次作业的最后一题不仅要运用类的封装性更要会使用正则表达式,正确写出可以符合条件的字符串。
7-2
该题代码如下:
import java.util.Scanner; class Date{ private int year; private int month; private int day; Date(){ this.setYear(0); this.setMonth(0); this.setDay(0); } Date(int year,int month,int day){ this.setYear(year); this.setMonth(month); this.setDay(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; } static boolean isLeapYear(int year) { if(year%4==0&&year%100!=0) return true; else if(year%400==0&&year%100==0) return true; else return false; } boolean checkInputValidity(int year,int month,int day) { if(year>=1900&&year<=2000&&month<=12&&month>=1&&day>=1&&day<=31){ if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ if(day<=31&&day>=1){ return true; } else{ return false; } } else if(month==4||month==6||month==9||month==11){ if(day<=30&&day>=1){ return true; } else{ return false;} } else if(month==2){ if(isLeapYear(year)){ if(day<=29&&day>=1){ return true; } else{ return false; } } else{ if(day<=28&&day>=1){ return true; } else{ return false; } } } } return false; } void nextDate(int year,int month,int day){ if(month==1||month==3||month==5||month==7||month==8||month==10){ if(day<31){ day++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } else{ day=1; month++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } } else if(month==4||month==6||month==9||month==11){ if(day<30){ day++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } else{ day=1; month++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } } else if(month==2){ if(isLeapYear(year)){ if(day<29){ day++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } else{ day=1; month++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } } else{ if(day<28){ day++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } else{ day=1; month++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } } } else if(month==12){ if(day<31){ day++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } else{ day=1; month=1; year++; System.out.println("Next day is:"+year+"-"+month+"-"+day); } } } } public class Main { public static void main(String[] args) { Scanner in =new Scanner(System.in); Date q=new Date(); int year=in.nextInt(); int month=in.nextInt(); int day=in.nextInt(); if(q.checkInputValidity(year, month, day)) { q.nextDate(year, month, day); } else { System.out.println("Date Format is Wrong"); } } }
度量:
分析: 这道题外部类中的方法与第二次作业中的方法很接近,但由于数据域的封装性使得类中块的深度特别高因为要调用私有属性的数据,但总的来说没有太大的难度。
7-3
这道题我一直没有完全过,只能达到部分正确,因为对于用正则表达式表示求导过程一直不知道应该怎么处理。
该题代码如下:
import java.util.*; class regex{ private String str; regex(String str) { this.str=str; } boolean panduan(String str) { if(str.matches("^(([-+]([1-9][0-9]*)(\\\\*x(\\\\^[+-]?([1-9][0-9]*))?))|(([1-9][0-9]*)\\\\*(x(\\\\^[+-]?([1-9][0-9]*))?))|([-+](x(\\\\^[+-]?([1-9][0-9]*))?))|([-+]([1-9][0-9]*))|(([1-9][0-9]*))|((x(\\\\^[+-]?([1-9][0-9]*))?)))+$")) { return true; } else { return false; } } void derivation(String str) { for(int i=0;i<str.length();i++) { if(str.matches("^([-+]?([1-9][0-9]*))+$")) { System.out.println("0"); } } } } public class Main { public static void main(String[] args) { Scanner sc =new Scanner(System.in); String str=sc.nextLine(); regex p =new regex(str); if(p.panduan(str)) { p.derivation(str); } else { System.out.println("Wrong Format"); } } }
度量:
分析: 这道题运用正则表达式来判断输入的数据是否正确是一个符合条件的一元多项式。
而正则表达式我是这样运用的:
- 匹配首项系数为1、指数可能存在;x(\\^[+-]?([1-9][0-9]*))?)
- 匹配首项带正系数且不为1、指数可能存在;([1-9][0-9]*)(\\*x(\\^[+-]?([1-9][0-9]*))?)
- 匹配首项或非首项、系数不为1、指数可能存在;[-+]([1-9][0-9]*)(\\*x(\\^[+-]?([1-9][0-9]*))?)
- 匹配首项或非首项、系数为1、指数可能存在;[-+](x(\\^[+-]?([1-9][0-9]*))?)
- 匹配首项或非首项常数;[-+]([1-9][0-9]*)
- 匹配首项或非首项常数;[-+]([1-9][0-9]*)
- 在表达式开始加^且末尾加$表示多次重复出现
将一元多项式分为了6种情况,这样就可以判断其输入多项式是否符合条件了。
但多项式求导只知道若输入常量可变为0,其余的就不知如何运用正则表达式去写。
三、三次作业遇到的bug及采坑心得
第一次作业
自己写的时候并没有遇到什么bug,写7-7题时一开始用的是冒泡排序给数组里的数排序后来发现直接用sort函数更加省时省力,而在帮别人看过代码发现有的同学在7-8题中的判断直角三角形中遇到bug,代码并没有正确判断出这个三角形是直角三角形,因为数据输入的都是实数型,程序在运行时会出现小数点后面多个数无法正确判断,这时可以运用数据类型的强制转换变成整数型或者将数据相减小于1e-6就可以正确判断出直角三角形。
第二次作业
7-1题写时不知道如何将二进制数转换成十进制数,后来用了Interage类可以将其直接转换,比很多用数学方法转换省事了许多,再用sunstring函数可以直接截取字符串中一段然后直接将其转换。
7-2题和7-3题写时自己没有遇到什么bug,都是直接就过了。
7-4题刚写完提交时是部分错误,因为闰年最后一天这一点没有完全过,后来发现是因为平年有365天而闰年有366天,这会导致从闰年变成平年时会有代码变化所以后来加上了这一情况,代码就过了。
7-5题跟前两题中的方法有相同的地方,但在判断是前几天时要将n分情况进行判断。
7-3题、7-4题、7-5题中闰年的判断方法:
public static boolean isLeapYear(int year) { if(year%4==0&&year%100!=0) return true; else if(year%400==0&&year%100==0) return true; else return false; }
第三次作业
7-1题自己写时没有遇到bug,但有同学问我localDate是什么类型数据,我输出日期用的是localDate.of函数,这样输出日期直接可以过。
7-2题自己写时没有遇到bug,整体思路跟第二次作业的后面几题很像。
7-3题自己遇到了很多问题,但现在有些问题都没有解决,刚开始写这题时还去自学了一下正则表达式,知道了如何用正则表达式表示一元多项式才开始写代码,但当时不知道如何用正则表达式写出一元多显示的求导过程,现在有些了解就是用正则表达式写出一元多项式求导后的式子并进行匹配,输出即可。
四、改进建议
题目集1
7-8题代码可以将if条件句用缩进变短,并将三角形类型可以整合在一起。
题目集2
7-4题和7-5题都有代码长度过长这一毛病,事实上可以将代码风格改变一下,并将类中的方法进行一些优化,可以适当减小其代码的时间复杂度。
题目集3
7-2题可以将外部类调用到主类中变为内部类,这样可以直接使用,而并不需要再声明类了。
7-3题正则表达式还可以进行替换,可以匹配到符合正则表达式的输入数据时直接将其替换成输出所要的已经求过导的一元多项式;输入一元多项式的数据存储可以改为用数组数列即ArraysList,更加方便数据的录用以及调用。
五、总结
这三次作业我收获颇多,学到了java语法的基本运用,以及加深了对于许多函数,包的理解比如Interage类,sort类,Random类等等,还有java中类的封装性,数据域的封装性,最重要的是学会了如何使用正则表达式,这实在不失为一个检查字符串格式的一把利器,同时在对于OO的学习中也改变了我学代码不喜欢换行加空格的风格。对于日后的学习我会继续加深对于面向对象这一概念更深的理解,还有java中的继承和多态以及对于正则表达式更多的运用使其真正的成为自己的“武器”。最后也希望在学习OO的过程中能在课堂上学习到更多书上本没有的但对我编代码十分有用的知识,写到更加具有代表性的题型,扩展自己的视野。