題目集1~3總結性Blog
一.前言
本篇文章將對我近期Java語言學習情況以及三次題目集作業進行分析總結。
題目集一:學習Java語言的入門題目,涉及if語句,for語句等多個常用知識點,可以通過這些題目學習Java語言的基本語法,鞏固基礎,題目數量適中,難度比較簡單,適合作為Java語言的入門練習。
題目集二:習題集二的難度相對於習題集一有了較大的改變,引入了字串處理String.用for迴圈對字串的遍歷處理,習題集二的第一題,IP地址的轉換,考察了我們對二進位制的處理怎樣應用到字串上,以及Java中的數學函式,Math.pow的使用,相對於習題集一的難度有所提升,習題集二的第二題考察了Java陣列的知識,也考察了我們在C語言中學習到的排序演算法,選擇排序,將兩個排序後的數組合併成一個新的陣列,習題集二的第三題第一次引入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程式碼。