學習java 題目集1~3的總結
前言:
題目集01題目較多,偏向於基本的java的一些程式碼、方法的用法
題目集02題目較少,考核重點為輸入字串,並對字串做變換或判斷及判斷其中某個或多個字元
題目集03題目最少難度也最高,考察的知識是類之間的關係及相互呼叫,是面向物件程式設計的基礎,建立的類繁多且複雜
(2)設計與分析:重點對題目的提交原始碼進行分析
SourceMonitor有關度量值知識資訊摘抄
度量值
1. 總行數(Lines)
包括空行在內的程式碼行數。
2. 語句數(Statements)
語句是以分號結尾的。分支語句if,迴圈語句for、while,跳轉語句goto都被計算在內。
3. 分支語句比例(Percent Branch Statements)
該值表示分支語句佔語句數目的比例,這裡的“分支語句”指的是使程式不順序執行的語句,包括if、else、for、while、break、continue、goto、switch、case、default和return。需要注意的是,do不被計算在內,因為其對應的while已經計算了。另外,異常處理的catch也被作為一個分支計算。
4. 註釋比例(Percent Lines with Comments)
該值指示註釋行(包括/*……*/和//……形式的註釋)佔總行數的比例。一般公司會對每個文件的header或者footer部分進行特殊的宣告註釋,可以再工程屬性中設定過濾,不計算在內。
5. 類個數(Classes)
包括class的個數。
6. 平均每個類方法數(Methods per Class)
平均每個類的方法數,即包括內聯和非內聯的,template函式在內的類方法數除以所有類的個數。
7. 函式個數(Functions)
所有函式的個數。
8. 平均每個函式包含的語句數目(Average Statements per Method)
總的函式語句數目除以函式數目得到該值。
9. 函式圈複雜度(Function Complexity)
圈複雜度指示一個函式可執行路徑的數目,以下語句為圈複雜度的值貢獻1:if/else/for/while語句,三元運算子語句,if/for/while判斷條件中的"&&"或“||”,switch語句,後接break/goto/ return/throw/continue語句的case語句,catch/except語句等。對應有最大圈複雜度(Max Complexity)和平均圈複雜度(Avg Complexity)。
10. 函式深度(Block Depth)
函式深度指示函式中分支巢狀的層數。對應有最大深度(Max Depth)和平均深度(Avg Depth)。
題目集02
7-2
根據Kiviat圖分析有四個維度的實際測量值超出了期望值範圍,應該更加註重一些邊界測試和其他細節上如“資料第幾位的校驗”。
題目集03
7-1
有其中四個實際測試值低於期望值,第一次接觸根據主方法來補充類的題型難免有些無措,但是這道題比較簡單隻需要掌握返回值得方法的寫法即可
7-2
本題程式碼中有兩個維度實際測試值超出期望值,在AVG depth、max complexity平均複雜程度 和最大複雜程度上超過了期望值,應該減少for、if等迴圈、判斷語句的巢狀層數以減少程式碼的複雜程度。
7-3
最大複雜程度實際測試值超出期望值依然是存在的問題,本題一些方法的建立與第二題大體相似,在類圖設計上這種聚合的關係我認為相對複雜,在類DateUtil中呼叫類Year中的方法時書寫起來十分麻煩。
而聚合二的這種聚合關係我認為更好。
(3)採坑心得:
題目集01:
7-1:身體質量指數測算
- Scanner input = new Scanner(System in);
有時候經常忘記什麼地方是空格什麼地方用“. ”連線:Scanner input = new Scanner(System.in);
- double BMI = countBMI();
有時候呼叫方法會忘記宣告其中的引數double BMI = countBMI(tall,weight);
- Math.pow(tall,2);
記得當時還不會用乘方的方法,現在記住了
7-2:長度質量計量單位換算
- double weight = input next.Double();
做的時候還是沒記住空格在哪”.”在哪(Ps。現在肯定知道了)double weight = input.nextDouble();
- System.out.println(countChange2(weight)+countChange1(loong));
輸出要求中2資料要以空格隔開,輸出時文字要用“ ”而方法卻不用
System.out.println(countChange2(weight)+" "+countChange1(loong));
- double pound = 0;
宣告變數是double型別,但是方法要求返回flout型別,所以在return之前將double型轉為flout型
float b = (float)pound; return b;
7-3:奇數求和
- int[] b = new int[ ];
後面[ ]中寫的是陣列的長度int[] b = new int[10];
7-4:房產稅費計算
- if(time=1)
有事粗心大意if語句中判斷時少一個“=”
- System.out.println((float)q+" "+(float)y+" "+(float)j+" "+(float)c);
輸出時資料精度不符合標準時要用flout轉換
7-5:遊戲角色選擇
- int player = nextInt();
有時候呼叫這個方法會忘記寫input,I也可能會忘記大寫 int player = input.nextInt();
7-6:學號識別
- str.length()
用於判斷字串長度
2.str.charAt(2)==2
判斷字串中第2位是不是2,因為是在字串中所以str.charAt(2)=='2'要加單引號
7-7:巴比倫法求平方近似值
1. while(Math.abs(nextGuess-lastGuess)>=0.00001)
Math.abs()計算變數平方的方法
7-8二進位制數值提取
- while(str.charAt(i)!='-' )
判斷字串是不是有“-”或者其他時候要加單引號
7-7:判斷三角形型別
- double x = input.nextDouble(), y = input.nextDouble(), z = input.nextDouble();
可以這樣一起輸入double型變數
題目集02
7-1字母數字轉換
- char cs[] = str.toCharArray();
toCharArray()將字串轉換為字元陣列
- byte words[] = new byte[cs.length];
位元組陣列用ASCLL碼來判定字母的大小
- println與print
println 在輸出之後會有一個換行而print卻沒有
題目集03
7-1用類解決一元二次方程
- 在建立Main class以外的class時要注意 { }的位置自己建立的class是在Main class外面的
public class Main {
public static void main(String[] args){
.......
}
}
class QuadraticEquation{
}
- 在類中建立方法時要注意返回的型別double、int.....或者是void不返回值
除void外如果沒有return 值 都會報錯
3.public QuadraticEquation(double a,double b,double c){
this.a = a;
this.b = b;
this.c = c;
}
變數名重複時在方法中要用this定義,來區分當前物件。
7-2:日期類設計
- 在日期類中建立的方法getPreviousNDays()中的記憶體超時
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;
int choice = input.nextInt();
if (choice == 1) { // test getNextNDays method
int m = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
m = input.nextInt();
if (m < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
} else if (choice == 2) { // test getPreviousNDays method
int n = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
n = input.nextInt();
if (n < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(
date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
System.out.println(date.getPreviousNDays(n).showDate());
} else if (choice == 3) { //test getDaysofDates method
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil fromDate = new DateUtil(year, month, day);
DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
System.out.println("The days between " + fromDate.showDate() +
" and " + toDate.showDate() + " are:"
+ fromDate.getDaysofDates(toDate));
} else {
System.out.println("Wrong Format");
System.exit(0);
}
}
else{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class DateUtil {
private int year;
private int month;
private int day;
public int a[] = new int[20];
public DateUtil(DateUtil d){
this.day = d.getDay();
this.month = d.getMonth();
this.year = d.getYear();
a[1] = 31; a[2] = 28; a[3] = 31; a[4] = 30; a[5] = 31; a[6] = 30;
a[7] = 31; a[8] = 31; a[9] = 30; a[10] = 31; a[11] = 30; a[12] = 31;
}
public DateUtil(int year, int month, int day){
this.year=year;
this.month=month;
this.day=day;
a[1]=31; a[2]=28; a[3]=31; a[4]=30; a[5]=31; a[6]=30;
a[7]=31; a[8]=31; a[9]=30; a[10]=31; a[11]=30; a[12]=31;
}
public boolean checkInputValidity(){
if(year>=1820&&year<=2020&&month>=1&&month<=12) {
if (this.isLeapYear(year)&&month==2 ) {
if(day<=29&&day>0)
return true;
else
return false;
}
else{
if(day>0&&day<=a[month])
return true;
else
return false;
}
}
else
return false;
}
public boolean isLeapYear(int year){
if(year%4==0&&year%100!=0||year%400==0)
return true;
else
return false;
}
public void setYear(int year) {
this.year = year;
}
public int getYear() {
return year;
}
public void setMonth(int month) {
this.month = month;
}
public int getMonth() {
return month;
}
public void setDay(int day) {
this.day = day;
}
public int getDay() {
return day;
}
public DateUtil getNextNDays(int m) {
while(m >= 366){
if(this.isLeapYear(year) && month <= 2){
if(month == 2 && day == 29){
day = 1;
month = 3;
}
year++;
m = m - 366;
}
else if(this.isLeapYear(year+1) && month > 2){
year++;
m = m - 366;
}
else{
year++;
m = m - 365;
}
}
a[2]=28;
for(int i=0;i<m;i++)
{
day++;
if(month==2&&this.isLeapYear(year)){
if(day>29){
month++;
day=1;
}
}
else {
if(day>a[month]){
month++;
day=1;
if(month>12)
{
year++;
month=1;
}
}
}
}
return this;
}
public DateUtil getPreviousNDays(int n){
while(n > 365){
if(this.isLeapYear(year) && month > 2){
n = n - 366;
year--;
}
else if(this.isLeapYear(year - 1) && month <= 2){
n = n - 366;
year--;
}
else{
n = n - 365;
year--;
}
}
for(int i = 0; i < n; i++){
day--;
if(day <= 0){
month--;
if(month <= 0){
month=12;
year--;
}
if(isLeapYear(year) && month == 2)
day=29;
else
day=a[month];
}
}
return this;
}
public boolean compareDates(DateUtil c){
if(this.year > c.getYear())
return true;
else if(this.year == c.getYear() && this.month > c.getMonth())
return true;
else if(this.year == c.getYear() && this.month == c.getMonth() && this.day > c.getDay())
return true;
return false;
}
public boolean equalTwoDates(DateUtil b){
if( b.getYear() != this.year)
return false;
else if( b.getDay() != this.day)
return false;
else if( b.getMonth() != this.month)
return false;
else
return true;
}
public int getDaysofDates(DateUtil date){
int res = 0;
a[2]=28;
boolean b = this.compareDates(date);
DateUtil d = new DateUtil(this);
if(b){
while(d.getYear()-date.getYear()>=2){
if(d.isLeapYear(d.getYear()) && d.getMonth() > 2)
res = res + 366;
else if(d.isLeapYear(d.getYear() - 1) && d.getMonth() <= 2)
res = res + 366;
else
res = res + 365;
d.setYear(d.getYear() - 1);
}
while(true){
if(d.equalTwoDates(date))
break;
res++;
d.setDay(d.getDay() - 1);
if(d.getDay() <= 0){
d.setMonth(d.getMonth() - 1);
if(d.getMonth() <= 0){
d.setMonth(12);
d.setYear(d.getYear() - 1);
}
if(isLeapYear(d.getYear()) && d.getMonth() == 2)
d.setDay(29);
else
d.setDay(d.a[d.getMonth()]);
}
}
}
else{
while(date.getYear() - d.getYear() >= 2){
if(d.isLeapYear(d.getYear()) && d.getMonth() <= 2)
res = res + 366;
else if(d.isLeapYear(d.getYear() + 1) && d.getMonth() > 2)
res = res + 366;
else
res = res + 365;
d.setYear(d.getYear() + 1);
}
while(true){
if(d.equalTwoDates(date))
break;
res++;
d.setDay(d.getDay() + 1);
if(isLeapYear(d.getYear()) && d.getMonth() == 2){
if(d.getDay() > 29){
d.setMonth(d.getMonth() + 1);
d.setDay(1);
}
}
else if(d.getDay() > d.a[d.getMonth()]){
d.setMonth(d.getMonth() + 1);
d.setDay(1);
if(d.getMonth() > 12){
d.setMonth(1);
d.setYear(d.getYear() + 1);
}
}
}
}
return res;
}
public String showDate(){
return year + "-" + month + "-" + day;
}
}
} 呼叫類創造一個新的物件,新物件中的變數,需要這樣來使用如:date.year
7-3聚合如何看類圖,菱形連線箭頭表示實體關係巨集,關係巨集分為兩類:A類,B類,但B類包含類,類是完整的,但B類是一部分,換句話說,B類不是一個水平關係,所以我們應該以A班的方式叫B班。
-
在這個主題中,主題要求建立四個類別,即歷史,今天,蒙蒂和年份,它們之間的關係是蒙蒂包含的年份,蒙蒂包含的日子,今天包含的日期。這就是為什麼我想在確定一年的年份之前在類DateUtil中呼叫IsleapYear()。獲取月份。一年。有葉的;當然,這就是我們在DateUtil類中所稱的IsleapYear()方法,而不需要新增日期。當然,當我們在主方法中呼叫它時,我們需要新增“日期”。
當我們呼叫上面描述的方法或變數時,這是非常複雜的,但是在Eclipse中,當我們進入Plus類時,這是非常複雜的。
7-4聚合二
- 在聚合二中依然是那四個類,但是這次不同的是類Day類Month類Year都包含於類DateUtil中,不同之處也是顯而易見的
如圖,(上圖是聚合二,下圖是聚合一)
我們可以發現原本在類Day類Month類Year中的方法到聚合二中有明顯變少,而類DateUtil中的方法卻明顯變多,類Day類Month類Year中有許多功能相似的方法,因此在聚合二中減少了像聚合一中的套娃行為,只需getYear().isLeapYear()如此就可以呼叫類Year中的方法。
(4)改進建議:對相應題目的編碼改進給出自己的見解,做到可持續改進
題目01
這次的題目集,思路較為清晰,難度較低,相較於在main方法中計算,我選擇在main方法外自己建立了一個方法來計算題目所需的資料,這樣一來邏輯變得更加簡單,我認為增加了可讀性,並且對於初學java如何建立方法、呼叫方法起到了一定的幫助。如7-1:
public static double countBMI(double tall,double weight){
double BMI = 0;
BMI = weight / Math.pow(tall,2);
return BMI;
}
題目03
7-2
考慮到第一個n天和第二個n天,因為一年的值範圍非常大,我決定從年開始,將年轉換為天,將月轉換為天,然後計算剩餘的天。因此,該程式碼中使用了幾個迴圈和幾個句子。為了返回正確的資料,這個計算方法已經修改了好幾次,幾乎已經過時,不適用於問題7-3。修改後,我將結果更改為計算連續累積。
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;
int choice = input.nextInt();
if (choice == 1) { // test getNextNDays method
int m = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
m = input.nextInt();
if (m < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
} else if (choice == 2) { // test getPreviousNDays method
int n = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
n = input.nextInt();
if (n < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(
date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
System.out.println(date.getPreviousNDays(n).showDate());
} else if (choice == 3) { //test getDaysofDates method
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil fromDate = new DateUtil(year, month, day);
DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
System.out.println("The days between " + fromDate.showDate() +
" and " + toDate.showDate() + " are:"
+ fromDate.getDaysofDates(toDate));
} else {
System.out.println("Wrong Format");
System.exit(0);
}
}
else{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class DateUtil {
private int year;
private int month;
private int day;
public int a[] = new int[20];
public DateUtil(DateUtil d){
this.day = d.getDay();
this.month = d.getMonth();
this.year = d.getYear();
a[1] = 31; a[2] = 28; a[3] = 31; a[4] = 30; a[5] = 31; a[6] = 30;
a[7] = 31; a[8] = 31; a[9] = 30; a[10] = 31; a[11] = 30; a[12] = 31;
}
public DateUtil(int year, int month, int day){
this.year=year;
this.month=month;
this.day=day;
a[1]=31; a[2]=28; a[3]=31; a[4]=30; a[5]=31; a[6]=30;
a[7]=31; a[8]=31; a[9]=30; a[10]=31; a[11]=30; a[12]=31;
}
public boolean checkInputValidity(){
if(year>=1820&&year<=2020&&month>=1&&month<=12) {
if (this.isLeapYear(year)&&month==2 ) {
if(day<=29&&day>0)
return true;
else
return false;
}
else{
if(day>0&&day<=a[month])
return true;
else
return false;
}
}
else
return false;
}
public boolean isLeapYear(int year){
if(year%4==0&&year%100!=0||year%400==0)
return true;
else
return false;
}
public void setYear(int year) {
this.year = year;
}
public int getYear() {
return year;
}
public void setMonth(int month) {
this.month = month;
}
public int getMonth() {
return month;
}
public void setDay(int day) {
this.day = day;
}
public int getDay() {
return day;
}
public DateUtil getNextNDays(int m) {
while(m >= 366){
if(this.isLeapYear(year) && month <= 2){
if(month == 2 && day == 29){
day = 1;
month = 3;
}
year++;
m = m - 366;
}
else if(this.isLeapYear(year+1) && month > 2){
year++;
m = m - 366;
}
else{
year++;
m = m - 365;
}
}
a[2]=28;
for(int i=0;i<m;i++)
{
day++;
if(month==2&&this.isLeapYear(year)){
if(day>29){
month++;
day=1;
}
}
else {
if(day>a[month]){
month++;
day=1;
if(month>12)
{
year++;
month=1;
}
}
}
}
return this;
}
public DateUtil getPreviousNDays(int n){
while(n > 365){
if(this.isLeapYear(year) && month > 2){
n = n - 366;
year--;
}
else if(this.isLeapYear(year - 1) && month <= 2){
n = n - 366;
year--;
}
else{
n = n - 365;
year--;
}
}
for(int i = 0; i < n; i++){
day--;
if(day <= 0){
month--;
if(month <= 0){
month=12;
year--;
}
if(isLeapYear(year) && month == 2)
day=29;
else
day=a[month];
}
}
return this;
}
public boolean compareDates(DateUtil c){
if(this.year > c.getYear())
return true;
else if(this.year == c.getYear() && this.month > c.getMonth())
return true;
else if(this.year == c.getYear() && this.month == c.getMonth() && this.day > c.getDay())
return true;
return false;
}
public boolean equalTwoDates(DateUtil b){
if( b.getYear() != this.year)
return false;
else if( b.getDay() != this.day)
return false;
else if( b.getMonth() != this.month)
return false;
else
return true;
}
public int getDaysofDates(DateUtil date){
int res = 0;
a[2]=28;
boolean b = this.compareDates(date);
DateUtil d = new DateUtil(this);
if(b){
while(d.getYear()-date.getYear()>=2){
if(d.isLeapYear(d.getYear()) && d.getMonth() > 2)
res = res + 366;
else if(d.isLeapYear(d.getYear() - 1) && d.getMonth() <= 2)
res = res + 366;
else
res = res + 365;
d.setYear(d.getYear() - 1);
}
while(true){
if(d.equalTwoDates(date))
break;
res++;
d.setDay(d.getDay() - 1);
if(d.getDay() <= 0){
d.setMonth(d.getMonth() - 1);
if(d.getMonth() <= 0){
d.setMonth(12);
d.setYear(d.getYear() - 1);
}
if(isLeapYear(d.getYear()) && d.getMonth() == 2)
d.setDay(29);
else
d.setDay(d.a[d.getMonth()]);
}
}
}
else{
while(date.getYear() - d.getYear() >= 2){
if(d.isLeapYear(d.getYear()) && d.getMonth() <= 2)
res = res + 366;
else if(d.isLeapYear(d.getYear() + 1) && d.getMonth() > 2)
res = res + 366;
else
res = res + 365;
d.setYear(d.getYear() + 1);
}
while(true){
if(d.equalTwoDates(date))
break;
res++;
d.setDay(d.getDay() + 1);
if(isLeapYear(d.getYear()) && d.getMonth() == 2){
if(d.getDay() > 29){
d.setMonth(d.getMonth() + 1);
d.setDay(1);
}
}
else if(d.getDay() > d.a[d.getMonth()]){
d.setMonth(d.getMonth() + 1);
d.setDay(1);
if(d.getMonth() > 12){
d.setMonth(1);
d.setYear(d.getYear() + 1);
}
}
}
}
return res;
}
public String showDate(){
return year + "-" + month + "-" + day;
}
}
}程式碼的篇幅不僅大幅縮短而且邏輯也更加清晰簡單。
(5)總結:
-
熟悉用java語言寫的一些簡單的程式,java和c語言寫的規範不一樣,比如{網站規範}
學習如何建立類,呼叫類建立新物件,呼叫其他類中的方法、物件和變數。
熟悉和掌握Java中的一些常用方法
一些基礎知識還沒有完全掌握,如中子類的輸入、繼承、母類與子類之間的關係、母類與子類之間的關係等一系列常用方法線上版本的程式碼發生的例子,然後解碼其含義,多閱讀一些關於多型性遺傳的論文,並參加一些網路論壇和其他討論。
在線上課的狀態必須始終保持,採用膝上型電腦和手寫體相結合的註冊方式,課後稍作整理
在我的業餘時間,在CSDN和一些開源網站上看到一些老手為我們寫的新階段的Java學習幫助解釋程式碼,註釋,理解,然後在eclipse中練習然後除錯除錯
儘快完成PTA實驗,用更多的時間總結PTA中的一些問題,以便下次有足夠的材料。