面向物件程式設計——前三次PTA題目集總結
一、前言
(1).第一次的題目集比較簡單,具體考察對java基本格式的掌握情況,如:輸入,輸出,條件判斷,迴圈等。對於演算法的要求較低,比較容易上手,題量也比較大。
(2).第二次的作業具體考察了string型別及其部分函式的使用,如substring,indexOf,lastIndexOf,equals等。在此基礎上也考察了for迴圈(可能是計數器)來判斷正誤條件。題量少
(3).第三次的作業加大了難度,在考察不同於C語言的類的使用的同時也考察了正則表示式,因此題量少。這也導致第三次題目集的提交正確率很低。說明我們對於Java的瞭解還不到位,處於萌新階段,還需要更加努力的去學習。
二、設計與分析
(1).第二次第二題為串列埠字元解析,如下圖:
先int count1 = number.indexOf('0'),再通過for迴圈使定位向後移動用count1 = number.indexOf('0',count1 + 11)相當於count1++,來定位到下一個有效資料前,利用count2完成有效資料個數的統計,count3來判斷奇偶校檢位的正誤,在末尾再把count3賦空,避免對下一組資料進行影響。具體為
(2).第三次第一題為點線形系列1-計算兩點之間的距離,如下圖:
計數器的方法導致這道題的程式碼看起來比較複雜。4個double型別的實數,兩個點的x,y座標,依次是x1、y1、x2、y2,兩個點的座標之間以空格分隔,每個點的x,y座標以英文“,”分隔。這種輸入格式要求了很多。首先是逗號,逗號分隔一個座標兩個double型數,說明逗號個數只能是二,且逗號下一位只能是double型的數,空格分隔了兩個座標,說明只能有一個空格,且空格下一位只能是double型的數。其次,符號不能有誤。最多隻能存在四個符號且符號下一位不能是符號。然後是小數點,小數點下一位必須是數字。最後是0。兩個0在一起則第三位不能是0.這是wrong format,wrong number of points 則在符合基本的基礎上與正確的格式成比例。在正則表示式裡有\p{}這種表達方式。我認為wrong number of points 這種情況是在格式正確的基礎上的,所以要先判斷wrong format。
(3).第三次第二題為點線形系列2-線的計算,如下圖:
這道題跟第一題很相似,只不過多了幾個演算法。其中多了一個重合的判斷,需加在演算法中。首先斜率的判斷就直接縱座標差和橫座標差求商。重合就是在縱座標相等基礎上橫座標相等。垂直於x軸就是橫座標差等於0,縱座標差不為0.點到直線的距離 三個點是否在一條線上就是
在斜率存在的基礎上讓其中兩條由兩點構成直線的斜率相等。判斷前兩個點構成的直線與後兩個點構成的直線是否平行。
計算前兩個點構成的直線與後兩個點構成的直線的交點,我參考網站上的演算法
第二題關鍵在於把錯誤輸入判斷與演算法結合在一起。分開寫還是很簡單的。但是合在一起還要對錯誤輸入判斷進行修改。
(4).第三次第三題為點線形系列3-三角形的計算,如下圖:
整個第三次習題集的錯誤格式判斷都是很相似的,輸入的格式基本一致。所以需要加深對類的使用。還有就是計算裡限制輸出的格式。是需要格外注意的。
經過詢問同學又在網上查詢後,我得到了一種新的方法
所以ystem.out.println((double)(Math.round(L*1000000)/1000000.0)+" "+(double)(Math.round(S*1000000)/1000000.0)+" "+(double)(Math.round(Cx*1000000)/1000000.0)+","+(double)(Math.round(Cy*1000000)/1000000.0))是我最終用到的限制的程式碼。
而判斷三角形的演算法我在計算的類中建立新方法,利用第一個習題集裡的部分程式碼
來完成。
三、踩坑心得
(1).第二次的第二題一開始採用計數器的方法,但是在第一組資料讀取後第二組及之後的幾組就沒辦法繼續在資料流裡提取了。所以在看了書上的indexOf函式後發現可以利用類似指標的方法,通過indexOf來定位所需要輸出的資料和捨棄無效資料。在用計數器的時候我發現判斷資料是否有效的條件很難表達。所以不能只考慮一種情況,可以嘗試多種方法。
(2).第三次的第一次我依舊採用計數器,這相對來說思考更簡單,但是由於需要判斷很多的條件,導致程式碼非常冗長,而且一看上去難以理解,不像正則表示式一樣,直接限制所輸入字串的格式,反而更加簡潔明瞭。
(3).第三次的第二題的輸入格式限制與第一題一致,但考慮到使用多個計數器比較麻煩,我就把計數器變成了boolean型,只使用兩個,來減輕複雜程度。我先寫了演算法,把正確格式所符合的情況都先搞定,再確定錯誤條件。
(4).第三次的最後一題跟第二題一樣,也是先寫演算法在加上錯誤判斷,但是限制輸出格式(四捨五入)我沒有搞明白,問了問同學又查了一下網路,才知道確切的方法。
四、改進建議
首先有些程式碼沒有完全符合規定,還需要繼續更正。比如最後一題,還需要繼續鑽研。利用正則表示式可以把式子寫的更簡單,清晰。不會讓程式碼看起來很亂,很長。程式碼的相容性比較低,需要加強類的使用。比如把錯誤判斷製成一個類,演算法做成一個類。在第二三題嘗試了方法的過載。把幾個計算用Work方法表示
1 import java.util.Scanner; 2 public class Main{ 3 public static void main(String[] args) { 4 Scanner input = new Scanner(System.in); 5 String s=input.nextLine(); 6 boolean find=false; 7 if(s.charAt(0)<49||s.charAt(0)>53||s.charAt(1)!=':') 8 find=true; 9 String a=s.substring(2); 10 int kong=a.indexOf(' '); 11 int dian=0; 12 if(kong==-1) 13 find=true; 14 int flag=0; 15 for(int i=0;i<a.length();i++) 16 { 17 if(a.charAt(i)==' '&&a.charAt(i+1)==' ') 18 flag=1; 19 } 20 do{ 21 dian=a.indexOf('.',dian); 22 if(dian!=-1) 23 { 24 if(a.charAt(dian+1)<48||a.charAt(dian+1)>57||a.charAt(dian-1)<48||a.charAt(dian-1)>57) 25 find=true; 26 dian++; 27 } 28 }while(dian!=-1); 29 if(s.length()==13) 30 { 31 if(s.charAt(0)=='1'&&s.charAt(5)=='0') 32 find=true; 33 } 34 String liner1[]=a.split(" "); 35 if(flag!=1) 36 { 37 for(int i=0;i<liner1.length;i++) 38 { 39 String[] liner2=liner1[i].split(","); 40 for(int j=0;j<liner2.length;j++) 41 { 42 if(liner2[j].charAt(0)<48||liner2[j].charAt(0)>57) 43 { 44 if(liner2[j].charAt(0)=='+'||liner2[j].charAt(0)=='-') 45 { 46 if(liner2[j].charAt(1)<48||liner2[j].charAt(1)>57) 47 find=true; 48 } 49 else 50 find=true; 51 } 52 if(liner2[j].length()>=2) 53 { 54 if(liner2[j].charAt(0)=='0'&&liner2[j].charAt(1)=='0') 55 find=true; 56 } 57 } 58 } 59 } 60 if(flag==1) { 61 System.out.println("Wrong Format"); 62 } 63 else if(find) 64 System.out.println("Wrong Format"); 65 else 66 Work(s); 67 } 68 public static void Work(String a) { 69 char num = a.charAt(0); 70 String liner[]=a.split(" "); 71 if(num == '1') 72 { 73 if(liner.length!=2) 74 { 75 System.out.println("wrong number of points"); 76 } 77 else 78 { 79 double x11=0.0,x12=0.0,y11=0.0,y12=0.0; 80 int a1,a2,a3,a4; 81 a1 = a.indexOf(':'); 82 a2 = a.indexOf(','); 83 a3 = a.indexOf(' '); 84 a4 = a.lastIndexOf(','); 85 x11 = Double.valueOf(a.substring(a1+1,a2).toString()); 86 y11 = Double.valueOf(a.substring(a2+1,a3).toString()); 87 x12 = Double.valueOf(a.substring(a3+1,a4).toString()); 88 y12 = Double.valueOf(a.substring(a4+1).toString()); 89 if(x12 - x11 == 0) 90 { 91 if(y12 - y11 != 0) 92 System.out.println("Slope does not exist"); 93 else 94 System.out.println("points coincide"); 95 } 96 else 97 { 98 double k1 = (y12 - y11) / (x12 - x11); 99 System.out.println(k1); 100 } 101 } 102 } 103 if(num == '2') 104 { 105 if(liner.length!=3) 106 { 107 System.out.println("wrong number of points"); 108 } 109 else{ 110 double x21=0.0,y21=0.0,x22=0.0,y22=0.0,x23=0.0,y23=0.0; 111 int a21,a22,a23,a24,a25,a26; 112 a21 = a.indexOf(':'); 113 a22 = a.indexOf(','); 114 a23 = a.indexOf(' '); 115 a24 = a.indexOf(',',a22+1); 116 a25 = a.lastIndexOf(' '); 117 a26 = a.lastIndexOf(','); 118 x21 = Double.valueOf(a.substring(a21+1,a22).toString()); 119 y21 = Double.valueOf(a.substring(a22+1,a23).toString()); 120 x22 = Double.valueOf(a.substring(a23+1,a24).toString()); 121 y22 = Double.valueOf(a.substring(a24+1,a25).toString()); 122 x23 = Double.valueOf(a.substring(a25+1,a26).toString()); 123 y23 = Double.valueOf(a.substring(a26+1).toString()); 124 if((x22 == x21 && y22 == y21) || (x23 == x21 && y23 == y22) || (x23 == x22 && y23 == y22)) 125 System.out.println("points coincide"); 126 else 127 { 128 double distance2 = Math.abs(((y22-y23)*x21+(x23-x22)*y21+x22*y23-y22*x23)/(Math.sqrt(Math.pow(y22-y23, 2) +Math.pow(x22-x23, 2)))); 129 System.out.println(distance2); 130 } 131 } 132 } 133 if(num == '3') 134 { 135 if(liner.length!=3) 136 { 137 System.out.println("wrong number of points"); 138 } 139 else 140 { 141 double x31=0.0,y31=0.0,x32=0.0,y32=0.0,x33=0.0,y33=0.0; 142 int a31,a32,a33,a34,a35,a36; 143 a31 = a.indexOf(':'); 144 a32 = a.indexOf(','); 145 a33 = a.indexOf(' '); 146 a34 = a.indexOf(',',a32+1); 147 a35 = a.lastIndexOf(' '); 148 a36 = a.lastIndexOf(','); 149 x31 = Double.valueOf(a.substring(a31+1,a32).toString()); 150 y31 = Double.valueOf(a.substring(a32+1,a33).toString()); 151 x32 = Double.valueOf(a.substring(a33+1,a34).toString()); 152 y32 = Double.valueOf(a.substring(a34+1,a35).toString()); 153 x33 = Double.valueOf(a.substring(a35+1,a36).toString()); 154 y33 = Double.valueOf(a.substring(a36+1).toString()); 155 if((x32 == x31 && y32 == y31) || (x33 == x31 && y33 == y32) || (x33 == x32 && y33 == y32)) 156 System.out.println("points coincide"); 157 else 158 { 159 double k31 = (y33 - y32) / (x33 - x32); 160 double k32 = (y33 - y31) / (x33 - x31); 161 double k33 = (y32 - y31) / (x32 - x31); 162 if(k31 == k32 || k31 == k33 || k32 == k33) 163 System.out.println("true"); 164 else 165 System.out.println("false"); 166 } 167 } 168 } 169 if(num == '4') 170 { 171 if(liner.length!=4) 172 { 173 System.out.println("wrong number of points"); 174 } 175 else 176 { 177 double x41=0.0,y41=0.0,x42=0.0,y42=0.0,x43=0.0,y43=0.0,x44=0.0,y44=0.0; 178 int a41,a42,a43,a44,a45,a46,a47,a48; 179 a41 = a.indexOf(':'); 180 a42 = a.indexOf(','); 181 a43 = a.indexOf(' '); 182 a44 = a.indexOf(',',a42+1); 183 a45 = a.indexOf(' ',a43+1); 184 a46 = a.indexOf(',',a44+1); 185 a47 = a.lastIndexOf(' '); 186 a48 = a.lastIndexOf(','); 187 x41 = Double.valueOf(a.substring(a41+1,a42).toString()); 188 y41 = Double.valueOf(a.substring(a42+1,a43).toString()); 189 x42 = Double.valueOf(a.substring(a43+1,a44).toString()); 190 y42 = Double.valueOf(a.substring(a44+1,a45).toString()); 191 x43 = Double.valueOf(a.substring(a45+1,a46).toString()); 192 y43 = Double.valueOf(a.substring(a46+1,a47).toString()); 193 x44 = Double.valueOf(a.substring(a47+1,a48).toString()); 194 y44 = Double.valueOf(a.substring(a48+1).toString()); 195 if((x44 == x43 && y44 == y43) || (x44 == x42 && y44 == x42) || (x44 == x41 && y44 == y41) || 196 (x43 == x42 && y44 == y42) || (x43 == x41 && y43 == y41) || (x42 == x41 && y42 == x41)) 197 System.out.println("points coincide"); 198 else 199 { 200 double k41 = (y42 - y41) / (x42 - x41); 201 double k42 = (y44 - y43) / (x44 - x43); 202 if((x42-x41==0&&x44-x43!=0)||(x44-x43==0&&x42-x41!=0)) 203 System.out.println("false"); 204 else 205 { 206 if(k41 == k42) 207 System.out.println("true"); 208 else 209 System.out.println("false"); 210 } 211 } 212 } 213 214 } 215 if(num == '5') 216 { 217 if(liner.length!=4) 218 { 219 System.out.println("wrong number of points"); 220 } 221 else 222 { 223 double x51=0.0,y51=0.0,x52=0.0,y52=0.0,x53=0.0,y53=0.0,x54=0.0,y54=0.0; 224 int a51,a52,a53,a54,a55,a56,a57,a58; 225 a51 = a.indexOf(':'); 226 a52 = a.indexOf(','); 227 a53 = a.indexOf(' '); 228 a54 = a.indexOf(',',a52+1); 229 a55 = a.indexOf(' ',a53+1); 230 a56 = a.indexOf(',',a54+1); 231 a57 = a.lastIndexOf(' '); 232 a58 = a.lastIndexOf(','); 233 x51 = Double.valueOf(a.substring(a51+1,a52).toString()); 234 y51 = Double.valueOf(a.substring(a52+1,a53).toString()); 235 x52 = Double.valueOf(a.substring(a53+1,a54).toString()); 236 y52 = Double.valueOf(a.substring(a54+1,a55).toString()); 237 x53 = Double.valueOf(a.substring(a55+1,a56).toString()); 238 y53 = Double.valueOf(a.substring(a56+1,a57).toString()); 239 x54 = Double.valueOf(a.substring(a57+1,a58).toString()); 240 y54 = Double.valueOf(a.substring(a58+1).toString()); 241 if((x54 == x53 && y54 == y53) || (x54 == x52 && y54 == x52) || (x54 == x51 && y54 == y51) || 242 (x53 == x52 && y53 == y52) || (x53 == x51 && y53 == y51) || (x52 == x51 && y52 == x51)) 243 System.out.println("points coincide"); 244 else{ 245 double k51 = (y52 - y51) / (x52 - x51); 246 double k52 = (y54 - y53) / (x54 - x53); 247 if(k51 == k52||(y51-y52)*(x53-x54)-(y53-y54)*(x51-x52)==0) 248 System.out.println("is parallel lines,have no intersection point"); 249 else 250 { 251 double X=(x53 * (y53-y54) * (x52-x51) - x51 * (y52-y51) * (x53-x54) + (y51-y53) * (x52-x51) * (x53-x54)) / ((y53-y54) * (x52-x51) - (y52-y51) * (x53-x54)); 252 double Y=(y51 * (x52-x51) * (y53-y54) - y53 * (x53-x54) * (y52-y51) + (x53-x51) * (y53-y54) * (y52-y51)) / ((x52-x51) * (y53-y54) - (x53-x54) * (y52-y51)); 253 if((X > x51 && X < x52) || (X > x52 && X < x51)) 254 { 255 if((Y > y51 && Y < y52) || (Y > y52 && Y < y51)) 256 System.out.println(X + "," + Y + " " + "true"); 257 else 258 System.out.println(X + "," + Y + " " + "false"); 259 } 260 else if((X > x53 && X < x54) || (X > x54 && X < x53)) 261 { 262 if((Y > y53 && Y < y54) || (Y > y54 && Y < y53)) 263 System.out.println(X + "," + Y + " " + "true"); 264 else 265 System.out.println(X + "," + Y + " " + "false"); 266 } 267 else 268 System.out.println(X + "," + Y + " " + "false"); 269 } 270 } 271 } 272 273 274 } 275 } 276 }
,然後過載。對類的使用是需要加強練習的。還要掌握Java中的重要方法。在寫程式碼時要參考書上的內容,特別是一些隱含的條件,當自己在盲目用的時候可能會報錯。
五、總結
這幾次的題都是為了強化我們對Java中類的認知。它有點像在C語言中自己編寫的函式庫,但是又不同於函式庫。類中能新增許多方法。我要加強對正則表示式的使用,不能只想到計數器,這就成了面向程式設計。學習Java就是為了實現面向物件,不能只按C語言的方式與思路進行編輯,雖然C語言提升強化了我們的程式碼基礎。在新的編譯器eclipse中有許多新的功能。我們可以利用debug來除錯自己的程式,而且eclipse中有識別錯誤的功能,可以自動提示錯誤的程式碼。作為一名初學者,我們需要掌握正則表示式,瞭解運用類與類之間的關係。首先,如果按照常規方法來判斷字串(計數器等),程式碼冗長,效率很低,利用正則表示式則可以提高效率,使程式碼更簡潔。
通過這幾次的作業我發現自己掌握的東西還是遠遠不夠的。我還需要繼續學習。