前三次題目集總結
- 2021 年 4 月 4 日
- 筆記
一、前言
首先,對於這三次題目集,我的收穫挺多。在第一次題目集中,主要是一些較為基礎的Java語法特性,有簡單數據的輸入輸出,對字元及字元串的簡單運用,然後就是一些簡單的if語句判斷和一維數組的簡單運用以及簡單的排序;在第二次題目集中,難度相對於第一次有所增加,這次的題目主要就是一些排序問題和判斷的問題,例如是否為閏年的判斷,以及每個月天數的判斷,其次就是對於輸入數據是否正確的判斷,這些都是本次題目集要認真考慮清楚的點,不能隨意亂寫;最後就是第三次題目集了,同時也是三次作業中最難的一次,在本次作業中主要就是鍛煉我們在編寫Java程式時多使用類來處理問題,這樣可以便於我們在後期對程式碼進行修改的過程中可以對有問題的類進行修改,而不用我們對整個一大串程式碼全部看一遍找問題了,也對類裡面的數據進行過public和private的處理,同時鍛煉了我們對於輸入正誤的判斷運用正則表達式來判斷。簡而言之,這三次題目集中,第一次題目集共有8道題目,但是題目還算比較簡單,第二次題目集減少到了5到題目,題目的難度也有所提高,而在第三次的題目集中,題目的數量雖然比前兩次都少,只有3道題,題量少,但是難度還比較大,用到的東西比較多,需要判斷的東西也比較多。對這三次題目集的總體題量和難度來講,感覺這三次題目的設置還比較合理,在題量多的時候,難度稍微簡單;在題量少的時候,難度便稍微提高。感覺這三次的題目集總體情況還可以,還比較好處理。
二、設計與分析
(1)題目集1:7-8
對於題目集1:7-8,是編寫一個程式,用於判斷三角的類型。這道題目我的程式碼使用的方式較為簡單,就是簡單的if語句判斷,對於符合每一種情況的三角形進行判斷,當符合每一種時就輸出哪種三角形,首先是判斷輸入的數據是否合法,再者判斷能不能構成三角形,其次判斷是否為等邊三角形,然後判斷是否為等腰直角三角形,然後就是判斷是不是等腰三角形是不是直角三角形,剩下的就是普通的三角形了。
由於沒有當時沒有類的概念,便只有一個主類,如下:
(2)題目集2:7-4
對於題目集2的7-4,是編寫一個程式求輸入日期的下一天,對於這題,首先要判斷輸入的年份是否合理,其次要對是不是閏年進行判斷,因為閏年的2月有29天,並且對於每一個月的最後一天要進行特殊判斷,因為下一天是下個月的第一天,不是簡單的日期加一;要做到對日期的全面考慮。相關圖片如下:
(3)題目集2:7-5
對於題目集2的7-5,是求輸入日期和輸入N值後的前N天,首先的考慮方法和上一題一樣,但是要注意N的不同取值代表的所求結果會有所不同,當N大於0時,結果是往前的N天,但是N小於0時則是當前日期的後N的絕對值天,當然,N=0時日期不變,做該道題目時想清楚這些就沒問題了,程式碼相關的圖片如下:
(4)題目集3:7-2
對於題目集3的7-2,是定義一個日期類來進行求解下一天,由題可知,該日期類包含有3個私有屬性year,month和day,還有11個public屬性,其實解該題不會難,只要把題目上面的類中的屬性全部都寫好、寫全,解該題就十分簡單了,注意一些細節就可以完成了;與程式碼相關的圖片如下:
(5)題目集3:7-3
對於題目集3的7-3,是要對一串的簡單多項式進行求導,其中還可能有輸入錯誤的數據類型,所以我想到的是將輸入的一連串字元串進行判斷,確定是正確的式子後再對其進行,所以我選擇使用正則表達式來對其先進行判斷,在判斷正確之後,再對符合正則表達式的式子進行每一個的拆分,分成每一個項之後再採用BigInteger,這個BigInteger是為了將數字和符號分離,更加有利於後面的求導,當數字準備好了之後,就可以對每一項進行相應的求導工作,但是求導之後要注意去判斷每一項的符號,一定要注意符號的問題,可以會出現漏符號或者多符號的問題,所以我就採用了對特殊情況進行特殊的判斷,這樣將有利於我的符號判斷,但是,由於我只寫了一個類來解決這個問題,所以當後面我去修改程式的時候發現自己寫的程式很是混亂,改起來也無從下手,讓我深刻認識到類的重要性,以下是程式碼的相關圖片:
三、踩坑心得
(1)對於題目集1的7-8,在編寫程式碼的過程中,判斷三角形的類型,首先應該想到符合成為三角形的條件,再對特殊的情況進行特殊的判斷,但是在判斷能不能是直角三角形或者是等腰直角三角形的時候,我們不能直接用如下的程式碼,是因為在Java中,涉及浮點數的計算都是近似的,因為這些數沒有以準確的精度來儲存,所以對於判斷直角就不能直接就使用下面的這種判斷來;
1 if(a*a+b*b==c*c||b*b+c*c==a*a||c*c+a*a==b*b)
而應該用比較大小的方式來判斷,就好比我用於判斷是否為等腰直角三角形的程式碼一樣,應該使用下面的這樣的程式碼(僅供參考):
1 else if(a==b&&a*a+b*b-c*c<0.0001||b==c&&b*b+c*c-a*a<0.0001||c==a&&c*c+a*a-b*b<0.0001) 2 { 3 System.out.println("Isosceles right-angled triangle");//輸入數據合法且能夠成等腰直角三角形 4 }
對於題目集1的7-8,以上的坑應該就是這道題最大的坑了,這個點比較難想到,其次就是建議盡量按照題目的判斷來進行編寫程式,這樣編寫出來的程式邏輯性比較強,更有利於後續檢查程式。
(2)對於題目集2的7-4,是求解輸入年份的下一天,其實這題並不是很難,只要思維邏輯很清晰,就很容易編寫出這題的程式碼來,要注意輸入的日期的合法,年份區間和月份的正確,比較難處理的應該就是對應每個月的天數的判斷了,因為每個月的天數都不一樣,而且特別是判斷閏年的二月的天數,又要判斷是不是閏年,而且還要注意2月時的天數的輸入是否合法;並且當輸入的是每個月的最後一天時,又得進行一下特殊的判斷,月份加一,然後將日期改成一號,對這些點進行了判斷和分析,這道題也就不怎麼難了,下面是我2月份求下一天的相關程式碼(僅供參考):
1 if(month==2) 2 { 3 if(isLeapYear(year)&&day==29) 4 { 5 month=3; 6 day=1; 7 } 8 else if(!isLeapYear(year)&&day==28) 9 { 10 month=3; 11 day=1; 12 } 13 else 14 { 15 day=day+1; 16 } 17 }
(3)對於題目集2的7-5,其實和題目集2的7-4很像,7-4是求下一天,而這個7-5則是求前N天,注意N的取值範圍即可,同時對於求前N天種的可能出現跳月的現象就要多多注意,比如3月跳至二月時就要注意該年是不是閏年,在二月份中是從28日算起還是從29日算起,同時當N為負值時,則所求的天數應該是往後計算,而不是往前計算,其他的需要注意的點大致上和題目集2的7-4差不多,注意邏輯思維的運用好就可以,下面給出N為正數且為3月時的判斷程式碼(僅供參考):
1 if(month==3) 2 { 3 if(isLeapYear(year)) 4 { 5 if(day<Math.abs(n)) 6 { 7 month=2; 8 day=29+day-Math.abs(n); 9 } 10 else 11 { 12 day=day-Math.abs(n); 13 } 14 } 15 else if(!isLeapYear(year)) 16 { 17 if(day<Math.abs(n)) 18 { 19 month=2; 20 day=28+day-Math.abs(n); 21 } 22 else 23 { 24 day=day-Math.abs(n); 25 } 26 } 27 }
(4)對於題目集3的7-2,是定義一個關於日期的類,並且求出輸入日期的下一天,該題的題目要求的結果是和題目集2的7-4一樣的,都是求下一天,但是該題目是要用類的方法來求解,需要我們設計類,在類設計中,同樣需要精確地判斷每一個輸入日期的合法性,要在Date類裡面全部實現,切記以後做題一定要認真看清楚題目的要求,我就沒看清楚題目的要求,就大致看了一下需要求的結果是什麼樣的,我就一味地找到題目集2的7-4,並且將相關的程式碼copy上去了,導致我一直有一個點沒有過,而且是一個十分低級的錯誤,在題目集2的7-4中,所求年份的區間為[1820,2020],而在這道題目裡面的年份區間為[1900,2000],導致我一直在找自己程式的錯誤,最後才發現原來是題目沒有看清,所以切記,以後做題一定不能看題目看一個大概,而是要認認真真地看清楚來,儘管題目可能大致一樣,但是最後也可能在一個很細微的點讓自己陷入沉思,所以一定要認真看題目!認真看題目!認真看題目!!!其次就是類裡面的setter和getter的方法的使用,這兩個點的使用還算是比較簡單的,上課認真聽老師講課或者課後自己認真看書,都是可以看懂的,不難,但是一定要認真學習。由於該題只是題目集2的7-4的類的設計,基本也就沒有什麼編寫程式方面的問題,若有什麼問題可以參考上面題目集2的7-4的心得,這題我踩的坑就是我看清楚題目,吃一塹長一智。以下是主類的程式碼(僅供參考 ):
1 public class Main { 2 3 public static void main(String[] args) { 4 // TODO 自動生成的方法存根 5 Scanner input = new Scanner(System.in); 6 Date date = new Date(); 7 date.setYear(input.nextInt()); 8 date.setMonth(input.nextInt()); 9 date.setDay(input.nextInt()); 10 if(!date.checkInputValidity()) 11 { 12 System.out.println("Date Format is Wrong"); 13 } 14 else 15 { 16 date.getNextDate(); 17 } 18 } 19 20 }
(5)對於題目集3的7-3,是一個比較難的一元簡單多項式的導函數求導問題,對於處理這個問題,我並沒有完全將程式碼調試完成解全部的點,有一些特殊的情況沒來得及考慮,但是,說實話,解決這道題目最關鍵的就是學好正則表達式,正則表達式對於判斷數據輸入是否正確極為重要,當然也是比較好學的,只要對老師的講解或者自己看書,一般都可以很輕鬆地拿下正則表達式,當然,我自己最後還是在bilibili上面找到的教學影片看,可以訪問//www.bilibili.com/video/BV1Ft4y1q7Vm?p=2進入bilibili裡面學習正則表達式,但僅供參考,具體看自己的實際情況。下面是我的判斷是否符合為簡單多項式的正則表達式(僅供參考):
1 String regexr2 ="(([-+]?[0]+)\\*x\\^([+-]?[\\d]+)" 2 + "|([-+]?[0]+)\\*x" 3 + "|[x]\\^([+-]?[0]+)" 4 + "|([-+]?[\\d]+)\\*x\\^([+-]?[0]+))";
還有一種常量的正則表達式建議自己去摸索,比較簡單,使用正則表達式就比較簡單地可以判斷輸入數據的正誤,更加利於我的判斷;其次就是求導的問題解決,可以使用拆分成數組的形式來計算當然也可以用正則表達式裡面的Pattern和Matcher來將那一大串的輸入數據分解成每一項進而求解,同時使用BigInteger方法應該也更加便捷,具體使用還看自己。但是由於我並沒有將這道題完整地解出來,所以也不知道後面是否還有難過的測試點,解到現在發現的問題基本上就這樣。
四、改進建議
(1)題目集1的7-8,比較簡單,當然也可以在後續的過程中可以對一般的三角形進行角度的判斷,進而對一般的三角形做到鈍角和銳角的判斷,更加有利於對三角形的形狀做進一步的區分,使得程式更加可行。
(2)題目集2的7-4,在後續和同學交流的過程中,發現了自己的程式碼有bug,我只是對2月的日期進行了判斷,但是對於那些月份只有30天的月份並沒有進行判斷,這是我在這道題目中發現的我的bug,如下圖:所以我的程式碼其實是不夠完整的,我應該將我的程式碼日期判斷那部分重新編寫。
(3)由於我的題目集2的7-5是仿照上一題寫的,所以上一題出現的問題在這一題也有,對於這一題,我認為N的區間可以擴大一點範圍,可以不用[-10,10],範圍可以跨月多一點,這樣就會使該程式的可行性更加高。
(4)題目集3的7-2和題目集2的7-4是一樣的,但是使用了類的概念,這樣對於修改程式,使程式修改完整更加方便。
(5)題目集3的7-3題目我沒有寫完,但是結束後問同學便發現自己是少了一些特殊情況的判斷,導致我的程式有一些測試點過不了,程式不夠完整,程式碼的解題思維還不夠強,這道題目十分鍛煉我們的邏輯思維和解題思維。
五、總結
在這三次的題目集中包含的內容很多,前2次的作業比較偏向於基礎,第一次的就是將之前學的C語言的編程用Java來寫出來,這樣,可以讓我們熟悉Java的編程方式以及複習一下C語言的相關知識,鞏固我們基礎知識,同時在第一次作業中收穫到了在Java中,涉及浮點數的計算都是近似的,因為這些數沒有以準確的精度來儲存,在以後這個可以作為一個知識點來記憶,並且在第一次作業中我了解到Java可以使用一個排序的方法Arrays.sort();可以直接排序,讓我進一步感受到了Java語言為什麼在程式語言中如此受歡迎的原因,也覺得感受到了Java語言的強大功能;在第二次作業中,我們開始接觸到一些關於Java的函數,例如Math.pow;Math.abs;等等一些常見的數學函數,同時在第二次作業中也特別能鍛煉我們的邏輯思維能力,在第二次作業中,有3道關於年份的判斷,還有一道關於IP地址的轉換,這都十分考驗我們的邏輯思維能力和思考的全面性,第二次作業也還不錯;第三次作業雖然說是難了一點,但是第三次作業感覺才更加有Java的味道了,第三次作業的前兩道題目,雖然都是比較簡單的題目,都是要求我們採用Java中類的使用來解題,採用類的方式來解題,讓我明白了為什麼Java使用類這一特性的原因,使用類可以讓我們在程式調試的過程中發現是哪個類有問題,而不用將整個程式碼全部看一遍,可以精確定位到是哪個類出了問題,有利於程式在修改的時候更加方便,對每一個不同的類屬性進行篩選,與此同時,在使用類的過程中,讓我學會了使用Java裡面的setter和getter方法,同時也懂得了private,public和protected的使用場所、使用方法以及它們之間的區別,對於boolean類型也有了更加深刻的了解,第三題則是最難的一道題目了,同時也是收穫最多的一道題目了,在解決這道題的過程中,我學到了正則表達式是運用,發現正則表達式對於判斷數據是否輸入正確十分便利,在以後的編程過程中也肯定是十分有幫助的,其次我還使用了正則表達式中的Pattern和Matcher,並且使用了find和group來對簡單多項式進行拆分,最後還使用了BigInteger來對每一項的數據進行分類和求導,這次作業鍛煉了我的邏輯思維,並且利於我來使用Java來進行編程的思想。
總的來說,這三次給了我許多的幫助,讓我了解到Java語言給程式設計師的巨大便利,同時也鍛煉了思考問題的能力,加強了我的邏輯思維,獲益匪淺。