一.前言
本篇文章将对我近期Java语言学习情况以及三次题目集作业进行分析总结。
题目集一:学习Java语言的入门题目,涉及if语句,for语句等多个常用知识点,可以通过这些题目学习Java语言的基本语法,巩固基础,题目数量适中,难度比较简单,适合作为Java语言的入门练习。
题目集二:习题集二的难度相对于习题集一有了较大的改变,引入了字符串处理String.用for循环对字符串的遍历处理,习题集二的第一题,IP地址的转换,考察了我们对二进制的处理怎样应用到字符串上,以及Java中的数学函数,Math.pow的使用,相对于习题集一的难度有所提升,习题集二的第二题考察了Java数组的知识,也考察了我们在C语言中学习到的排序算法,选择排序,将两个排序后的数组合并成一个新的数组,习题集二的第三题第一次引入Java类的概念,Java类的单一职责,要对类实现的功能进行封装,从而进而判断第几年第几天是星期几,这里比较难过的一个知识点是闰年的情况需要另行判断,习题集二的第四题也是对Java面向对象的类的集体运用的一个题,这两个题都是对于类的考察,让我们对于类有了一个很好的理解,习题集二的第五题是这次题目最难和测试点最多的题,在通过第五题的测试点时花了很多时间。
题目集三:学习Java语言的进阶题目,涉及到Java语言中特有的类的运用以及正则表达式的运用,通过这些题目,可以引起我们对面向对象的思考,初步理解面向对象的思想,题目数量较少,但难度对于初学者较大,尤其是正则表达式的部分,刚拿到题目时,不知该从何处下手。
题目集一 7-8
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner x=new Scanner(System.in); double a,b,c,temp; a=x.nextFloat();b=x.nextFloat();c=x.nextFloat(); if(a>b){ temp=a;a=b;b=temp; } if(a>c){ temp=a;a=c;c=temp; } if(b>c){ temp=b;b=c;c=temp; } if(a>=1&&a<=200&&b>=1&&b<=200&&c>=1&&c<=200){ if(a+b>c){ if(a==b&&b==c) System.out.println("Equilateral triangle"); else if(a*a+b*b-c*c<0.000001&&a==b) System.out.println("Isosceles right-angled triangle"); else if((a==b&&a!=c)||(a==c&&a!=b)||(b==c&&b!=a)) System.out.println("Isosceles triangle"); else if(a*a+b*b-c*c<0.000001) System.out.println("Right-angled triangle"); else System.out.println("General triangle"); } else System.out.println("Not a triangle"); } else System.out.println("Wrong Format"); } }
两边之和大于第三边,两边之差小于第三边。这是我们设计函数的主题思路,也是支持我们的代码的中心思想。
可以用if-else嵌套来做,我们第一步先来判断输入的数据是否合法,题目中已经给出了三条边的取值范围,先来判断输入三条边是否在指定的区间,不是的话就输出“Wrong Format”,之后还要判断三条边是否能构成三角形,利用三角形两边之和大于第三边就可判断。
第二步便是判断三角形类型了,这里就可以利用勾股定理和对三角形的定义来判断,用勾股定理判断直角,三边相等判断直角三角形,基本逻辑就这样,跟C语言没有太大的区别。
题目集二7-4:
题目集二7-4考察了类与对象,这对当时的我来说还很困难,很难考虑出所有的情况,也难以通过创造类去解决问题。好在老师给了在题目中给了很多提示,否则要我自己去建立并调用这些类。
求下一天
输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[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) ; //求输入日期的下一天
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int year = in.nextInt();
int month = in.nextInt();
int day = in.nextInt();
Main.nextDate(year,month,day);
}
public static boolean isLeapYear(int year) {
boolean isLeapYear;
if( isLeapYear = (year % 4 == 0 && year % 100 !=0 )||year % 400 == 0);
return true;
}
public static boolean checkInputValidity(int year,int month,int day) {
int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year))
aa[2] = 29;
boolean checkInputValidity;
if( checkInputValidity = (year>=1820&&year<=2020&&month>0&&month<=12&&day<=aa[month]&&day>0));
return true;
}
public static void nextDate(int year,int month,int day) {
int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year))
aa[2] = 29;
int a = 0,b = 0,c = 0;
if(checkInputValidity(year,month,day)) {
if(month==12) {
if(day==aa[month]) {
a = year++;
b = 1;
c = 1;}
if(day>0&&day<aa[month])
{a = year;
b = month;
c =day ++;
}
if(month<=12) {
if(day==aa[month]) {
a = year;
b = month ++;
c = 1;}
if(day>0&&day<aa[month])
{a = year;
b = month;
c = day++;
}
}
System.out.println("Next date is:"+a+"-"+b+"-"+c);
}
else System.out.println("Wrong Format");
}}
这道题目开始涉及JAVA的方法,其实和C语言的函数差不多,题目开始已经给出了大概的框架,除开主方法,我们需要实现三个功能,判断闰年,判断合法,还有输出下一天,前面两个方法很简单,判断闰年用是4的倍数,且不是100的倍数的年份或者能被400整除的年份这个条件来实现,判断非法则用题目给出的区间来判断,不过需要要注意的是平年的2月29也属于非法输入。
7-5 求前N天 (30 分)
输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。
import java.util.Scanner; 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(); int n=input.nextInt(); boolean a=checkInputValidity( year, month, day); if(n<-10||n>10) { System.out.println("Wrong Format"); } else { if(a==false) { System.out.println("Wrong Format"); } if(a==true) { Date(year,month,day,n); } } } public static boolean isLeapYear(int year) { boolean isLeapYear; isLeapYear= (year%4==0&&year%100!=0)||year%400==0; return isLeapYear; } 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)) { if((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day<=31) return true; else if((month==4||month==6||month==9||month==11)&&day<=30) return true; else if(month==2&&day<=29) return true; else return false; } else { if((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day<=31) return true; else if((month==4||month==6||month==9||month==11)&&day<=30) return true; else if(month==2&&day<=28) return true; else return false; } } } public static void Date(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)&&(day-n)<=31) { day=day-n; } else if((month==1||month==3||month==5||month==7||month==8||month==10)&&(day-n)>31) { month++; day=day-n-31; } else if((month==4||month==6||month==9||month==11)&&(day-n)<=30) { day=day-n; } else if((month==4||month==6||month==9||month==11)&&(day-n)>30) { month++; day=day-n-30; } else if(month==2) { if(isLeapYear(year)) { if((day-n)<=29) day=day-n; else { month++; day=day-n-29; } } else { if((day-n)<=28) day=day-n; else { month++; day=day-n-28; } } } else if(month==12&&(day-n)>31) { day=day-n-31; month=1; year++; } } else if(n>0) { if(day>n) { day=day-n; } else if((month==5||month==7||month==10||month==12)&&day<=n) { month--; day=30+day-n; } else if((month==2||month==4||month==6||month==8||month==9||month==11)&&day<=n) { month--; day=31+day-n; } if(month==3&&day<=n) { if(isLeapYear(year)) { month=2; day=day+29-n; } else { month=2; day=day+28-n; } } else if (month==1&&day<=n) { year--; month=12; day=day+31-n; } } System.out.print(n +" days ago is:"+year+"-"+month+"-"+day); } }
这个题目与求下一天的题目有着异曲同工之处,我们也是按照上一题的思路,将上一题的方法可以直接带过来使用,就是最主要的方法不同,求前N天的方法我们需要思考。
7-2 定义日期类
定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
要求:Date类结构如下图所示:
import java.util.Scanner; //Date类 class Date{ static int year; static int month; static int day; //创建年月日的构造方法 public Date(int year,int month,int day){ Date.year =year; Date.month =month; Date.day =day; } public Date() { int year,day; } //getter public int getYear(){ return year; } public int getMonth() { return month; } public int getDay() { return day; } //setter public void setYear(int year) { this.year = year; } public void setMonth(int month) { this.month = month; } public void setDay(int day) { this.day = day; } //判断year是否为闰年 public static boolean isLeapYear(int year) { boolean isLeapYear; isLeapYear = ((year % 4 == 0 && year % 100 !=0 )||year % 400 == 0); return isLeapYear; } //判断输入日期是否合法 public static boolean checkInputValidity(int year, int month, int day) { boolean checkInputValidity; int[] a=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31}; if(!isLeapYear(year)) a[2] = 28; checkInputValidity = (year>=1900&&year<=2000&&month>0&&month<=12&&day<=a[month]&&day>0); return checkInputValidity; } //得到下一天 public static void getnextDate(int year,int month,int day) { int[] a=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31}; int d=0; int m=0; if(!isLeapYear(year))//如果不是闰年 a[2] = 28; if(checkInputValidity(year,month,day)) {//如果输入的数字合法 if(month==12) {//如果是12月 if(day==a[month]) {//如果是12月的最后一天 year = year+1; m = 1; d=1; } else{//如果不是12月的最后一天 m=month; d =day +1; } } else {//如果不是12月 if(day==a[month]) {//如果是该月的最后一天 m = month + 1; d = 1; } else{//如果不是该月的最后一天 m=month; d = day+1; } } System.out.println("Next day is:"+year+"-"+m+"-"+d); } else//如果输入的数字非法 System.out.println("Date Format is Wrong"); } } //主类 public class Main { //主函数 public static void main(String[] args) { Scanner x=new Scanner(System.in); Date rq=new Date(); rq.setYear(x.nextInt());//得到年份 rq.setMonth(x.nextInt());//得到月份 rq.setDay(x.nextInt());//得到天 rq.getnextDate(rq.getYear(), rq.getMonth(),rq.getDay()); } }
在写Date类使,我们也要特别注意类的封装,明白且正确使用类的封装。
7-3 一元多项式求导(类设计)
编写程序性,实现对简单多项式的导函数进行求解。详见作业指导书。
输入格式:
在一行内输入一个待计算导函数的表达式,以回车符结束。
输出格式:
- 如果输入表达式不符合上述表达式基本规则,则输出“Wrong Format”。
- 如果输入合法,则在一行内正常输出该表达式的导函数,注意以下几点: 结果不需要排序,也不需要化简;
- 当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
- 当输出结果第一项系数符号为“+”时,不输出“+”;
- 当指数符号为“+”时,不输出“+”;
- 当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可。
String aa="[-+]?"; String bb="([0-9]*)?\\*?"; String cc="(x(\\^[+-]?[0-9]+)?)?"; String dd="(\\s*)?"; String totalRegex = "([-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[0-9]+)?)+"; String sbuRegex = "[-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[0-9]+)?"; String sbuRegex1="[-+]?([1-9]+[0-9]*)"; String sbuRegex2="[-+]?([1-9]+[0-9]*)(\\*)x";
String sbuRegex3 = "[-+]?([1-9]+[0-9]*(\\*))?x(\\^[+-]?[0-9]+)?";
如果输入的字符串符合多项式的要求,那么就进行多项式的拆解,在这里运用正则表达式,我的正则表达式有很多,来进行多项式的多种情况,例如:
String aa="[-+]?"; String bb="([0-9]*)?\\*?"; String cc="(x(\\^[+-]?[0-9]+)?)?"; String dd="(\\s*)?"; String totalRegex = "([-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[0-9]+)?)+"; String sbuRegex = "[-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[0-9]+)?"; String sbuRegex1="[-+]?([1-9]+[0-9]*)"; String sbuRegex2="[-+]?([1-9]+[0-9]*)(\\*)x"; String sbuRegex3 = "[-+]?([1-9]+[0-9]*(\\*))?x(\\^[+-]?[0-9]+)?";
这些正则表达式对应多种情况下的多项式。
接着我写了多个方法来进行判断,判断输入的多项式,满足以上哪一种正则表达式,如果满足,就按照相对应的拆分方法进行拆分,然后在输出求导后的多项式,例如:
void ppp(String biaodashi1) { boolean bl = Pattern.matches(sbuRegex1, biaodashi1); if (bl == true) { System.out.println(0); } boolean b2 = Pattern.matches(sbuRegex2, biaodashi1); if (b2 == true) { String[] arr1 = biaodashi1.split("\\*x"); BigInteger m = BigInteger.valueOf(Integer.parseInt(arr1[0])); for (int i = 0; i < arr1.length; i++) { System.out.println(m); } } else { Pattern pattern = Pattern.compile(sbuRegex3); Matcher matcher = pattern.matcher(biaodashi1); ArrayList<String> List = new ArrayList<String>(); ArrayList<String> shuList = new ArrayList<>(); while (matcher.find()) { String tmp = matcher.group(); List.add(tmp); int begin = matcher.start(); int end = matcher.end(); // System.out.println("项:"+tmp+" begin:"+begin+" end:"+ (end-1)); if (end == biaodashi1.length()) break; } for (int i = 0; i < List.size(); i++) { boolean b3 = Pattern.matches("[-+]?([1-9]+[0-9]*(\\*))x(\\^[+-]?[0-9]+)", List.get(i)); boolean b4 = Pattern.matches("[-+]?x(\\^[+-]?[0-9]+)", List.get(i)); boolean b5 = Pattern.matches("[-+]?x", List.get(i)); if (b3 == true) { String[] arr2 = List.get(i).split("\\*x\\^"); BigInteger m = BigInteger.valueOf(Integer.parseInt(arr2[0])); BigInteger n = BigInteger.valueOf(Integer.parseInt(arr2[1])); BigInteger k = new BigInteger("0"); BigInteger q1 = new BigInteger("1"); if(n.compareTo(k)==0){ System.out.print("Wrong Format"); break; } else { if (i == 0) System.out.print(m.multiply(n) + "*x^" + n.subtract(q1)); else { if (m.multiply(n).compareTo(k)==1) System.out.print("+" + m.multiply(n)+ "*x^" + n.subtract(q1)); if (m.multiply(n).compareTo(k)==-1) System.out.print(m.multiply(n)+ "*x^" +n.subtract(q1)); } } } else if(b4==true&&i==0){ String[] arr3 = List.get(i).split("x\\^"); String b="-"; if(arr3[0].equals(b)){ BigInteger p = BigInteger.valueOf(Integer.parseInt(arr3[1])); BigInteger k = new BigInteger("2"); BigInteger q1 = new BigInteger("1"); if(p.compareTo(k)==0){ System.out.print("-"+p+"*x"); } else System.out.print("-"+p + "*x^" + p.subtract(q1)); } else{ BigInteger p = BigInteger.valueOf(Integer.parseInt(arr3[1])); BigInteger k = new BigInteger("2"); BigInteger q1 = new BigInteger("1"); if(p.compareTo(k)==0){ System.out.print("-"+p + "*x"); } else System.out.print("-"+p + "*x" +p.subtract(q1) ); } /* for(int q = 0;q< arr3.length;q++){ System.out.println(arr3[q]); }*/ } else if(b5==true){ String[] arr4 = List.get(i).split("x"); String b="-"; if(arr4[0].equals(b)){ System.out.print(-1); } else System.out.print(1); } else { String[] arr5 = List.get(i).split("\\*x"); BigInteger m = BigInteger.valueOf(Integer.parseInt(arr5[0])); System.out.print(m); } }
这个题目我实在是不会。正则表达式没有掌握。
三丶踩坑心得
对于初次接触类的时候,还有一些不太理解,尽管有了一些认识,但是还是不够熟悉,还要多加联系与运用。
没有搞清楚类的含义,不能够熟练地使用类,单纯的以为类只是另一种方法,结果最开始编写程序的时候出现了大量的错误。
多项式求导题目中,我需要将正则表达式通透理解,并且能够熟练运用,我认为我写的需要改进的地方在能把一些重复的方法功能写入同一个方法中。
四丶改进建议
个人编程能力较差,争取能够查漏补缺能够跟上进度。
五丶总结
要通过mooc自学相关Java内容。应该要在课外提前学习,而不是在每次发布作业的时候发现自己不会的内容才去学。
自己写的代码过于混乱,最后还是需要参考网上的内容才能写出来功能完善的代码。要学习编写结构清晰、逻辑正确、功能完善的java代码。