面对对象程序设计题目分析与心得2
一、前言
1.第四次题目集
此次题目集所遇到的知识点有正则表达式,字符串比较方法equals,对字符串用split方法分割提取字符串中数字(Ascll码)并用parseInt方法转化为可相加的数字,for-each循环遍历数组或者Arraylist容器;还有考查继承,用DecimalFormat类格式化输出,四边形判定方法,运用面积大小关系判断一个点与多边形的位置关系,对于四个点是否有冗余点,构成四边形或三角形;考查对题目的仔细分析。
2.期中考试
主要考查继承与多态,根据题目所给类图编写程序,对输入进行限制,运用Math类进行数学运算,使用String.format方法格式化输出,抽象类作为父类语法考查;运用ArrayList类中add和remove方法进行增加和删除。
3.第五次题目集
此次较第四次增加一个五边形的类,五边形的判定方法,对五个点是否有冗余的判断,判断两个多边形的位置关系,求两个多边形的公共区域,同样考查继承,大体上与第四次考查的内容差不多。
4.超星
超星的题目主要来源于老师课堂布置的设计类图
四个的题量都不多,第五次甚至只有一个题,较为简单的是期中考试,基本上仅仅考查继承并且给出了类图,其次是第四次,最后是第五次。
二、设计与分析
1.第四次题目集
(1)类图
(2)圈复杂度
(3)解释
此题类与类之间没有太大的联系,都是根据题目相应选项调用相应方法。
Judge复杂度过高是因为if-else语句太多,然后根据返回值来确定哪些点构成三角形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /* * 输入:用户输入点集 * 返回:1:2 3 4构成三角形,2:1 3 4构成三角形,3:1 2 4构成三角形,4:1 2 3构成三角形,0:四个点不构成三角形 */ public static int f(ArrayList<Point> ps){ // 判断四个点是否构成三角形 if (ps.size()== 5 ) { Line L1 = new Line(ps.get( 2 ), ps.get( 4 )); //第二个点与第四个点构成的直线 Line L2 = new Line(ps.get( 1 ), ps.get( 3 )); //第一个点与第三个点构成的直线 if (L1.isBetween(ps.get( 1 ))&& !L1.isBetween(ps.get( 3 ))|| ps.get( 1 ).isCoincide(ps.get( 2 ))|| ps.get( 1 ).isCoincide(ps.get( 4 ))) { return 1 ; } else if (L2.isBetween(ps.get( 2 ))&& !L2.isBetween(ps.get( 4 ))|| ps.get( 2 ).isCoincide(ps.get( 1 ))|| ps.get( 2 ).isCoincide(ps.get( 3 ))) { return 2 ; } else if (L1.isBetween(ps.get( 3 ))&& !L1.isBetween(ps.get( 1 ))|| ps.get( 3 ).isCoincide(ps.get( 2 ))|| ps.get( 3 ).isCoincide(ps.get( 4 ))) { return 3 ; } else if (L2.isBetween(ps.get( 4 ))&& !L2.isBetween(ps.get( 2 ))|| ps.get( 4 ).isCoincide(ps.get( 1 ))|| ps.get( 4 ).isCoincide(ps.get( 3 ))) { return 4 ; } else return 0 ; } else { Line L1 = new Line(ps.get( 2 ), ps.get( 4 )); //第二个点与第四个点构成的直线 Line L2 = new Line(ps.get( 3 ), ps.get( 5 )); //第一个点与第三个点构成的直线 if (L2.isBetween(ps.get( 2 ))&& !L2.isBetween(ps.get( 4 ))|| ps.get( 2 ).isCoincide(ps.get( 3 ))|| ps.get( 2 ).isCoincide(ps.get( 5 ))) { return 1 ; } else if (L1.isBetween(ps.get( 3 ))&& !L1.isBetween(ps.get( 5 ))|| ps.get( 3 ).isCoincide(ps.get( 2 ))|| ps.get( 3 ).isCoincide(ps.get( 4 ))) { return 2 ; } else if (L2.isBetween(ps.get( 4 ))&& !L2.isBetween(ps.get( 2 ))|| ps.get( 4 ).isCoincide(ps.get( 3 ))|| ps.get( 4 ).isCoincide(ps.get( 5 ))) { return 3 ; } else if (L1.isBetween(ps.get( 5 ))&& !L1.isBetween(ps.get( 3 ))|| ps.get( 5 ).isCoincide(ps.get( 2 ))|| ps.get( 5 ).isCoincide(ps.get( 4 ))) { return 4 ; } else return 0 ; } } |
这里将线作为四边形的属性是为了方便,在网上一顿搜索后找到四边形的面积计算方法
1 2 3 4 5 6 7 8 | public double getArea() { // 获取四边形面积 Point x = new Point(l1.getMiddlePoint().x, l1.getMiddlePoint().y); Point y = new Point(l3.getMiddlePoint().x, l3.getMiddlePoint().y); Point z = new Point(l2.getMiddlePoint().x, l2.getMiddlePoint().y); Line l = new Line(x, y); return ( double ) 2 * l.getDistance(z) * x.getDistance(y); } |
(4)心得
四边形中将线作为属性不好,这样可能会造成四边形的点和线不对应的情况,后续在类中添加方法getsideline;知道怎么样的点才算冗余点,但是根据返回值来判断哪些点的方法不好,后续改为返回点集;知道四边形面积求法;由于没用继承,所以出现了很多代码重复。
(5)整题源码

1 import java.text.DecimalFormat; 2 import java.util.ArrayList; 3 import java.util.Scanner; 4 5 public class Main { 6 public static void main(String[] args) { 7 8 Scanner in = new Scanner(System.in); 9 String s = in.nextLine(); 10 InputData d = new InputData(); 11 ParseInput.paseInput(s, d); 12 int choice = d.getChoice(); 13 ArrayList<Point> ps = d.getPoints(); 14 switch (choice) { 15 case 1: 16 handle1(ps); 17 break; 18 case 2: 19 handle2(ps); 20 break; 21 case 3: 22 handle3(ps); 23 break; 24 case 4: 25 handle4(ps); 26 break; 27 case 5: 28 handle5(ps); 29 break; 30 } 31 32 } 33 34 // 输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。 35 public static void handle1(ArrayList<Point> ps) { 36 PointInputError.wrongNumberOfPoints(ps, 4); 37 Quadrilateral q = new Quadrilateral(ps.get(0), ps.get(1), ps.get(2), ps.get(3)); 38 System.out.println(q.isQuadrilateral()+" "+q.isParallelogram()); 39 } 40 41 // 输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral" 42 public static void handle2(ArrayList<Point> ps) { 43 PointInputError.wrongNumberOfPoints(ps, 4); 44 Quadrilateral q = new Quadrilateral(ps.get(0), ps.get(1), ps.get(2), ps.get(3)); 45 if(!q.isQuadrilateral()) { 46 System.out.println("not a quadrilateral"); 47 System.exit(0); 48 } 49 System.out.println(q.isDiamond()+" "+q.isDectangle()+" "+q.isSquare()); 50 } 51 52 // 输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral" 53 public static void handle3(ArrayList<Point> ps) { 54 PointInputError.wrongNumberOfPoints(ps, 4); 55 Quadrilateral q = new Quadrilateral(ps.get(0), ps.get(1), ps.get(2), ps.get(3)); 56 if(!q.isQuadrilateral()) { 57 System.out.println("not a quadrilateral"); 58 System.exit(0); 59 } 60 System.out.println(q.isConcave()+" "+OutFormat.doubleFormat(q.getPerimeter())+" "+OutFormat.doubleFormat(q.getArea())); 61 } 62 63 public static void handle4(ArrayList<Point> ps) { 64 PointInputError.wrongNumberOfPoints(ps, 6); 65 int n = Judge.f(ps); 66 Triangle a = new Triangle(); 67 Line l = new Line(ps.get(0), ps.get(1)); 68 switch(n) { 69 case 1:a.setX(ps.get(3));a.setY(ps.get(4));a.setZ(ps.get(5));break; 70 case 2:a.setX(ps.get(2));a.setY(ps.get(4));a.setZ(ps.get(5));break; 71 case 3:a.setX(ps.get(2));a.setY(ps.get(3));a.setZ(ps.get(5));break; 72 case 4:a.setX(ps.get(2));a.setY(ps.get(3));a.setZ(ps.get(4));break; 73 case 0:{Quadrilateral q = new Quadrilateral(ps.get(2), ps.get(3), ps.get(4), ps.get(5)); 74 if(!q.isQuadrilateral()) { 75 System.out.println("not a quadrilateral or triangle"); 76 System.exit(0); 77 } 78 if(q.judgeLineCoincide(l)) { 79 System.out.println("The line is coincide with one of the lines"); 80 System.exit(0); 81 } 82 System.out.print(q.getIntersections(l).size()); 83 if(q.getIntersections(l).size()==2) { 84 double[] area = q.calArea(q.getIntersections(l).get(0), q.getIntersections(l).get(1)); 85 System.out.println(" "+OutFormat.doubleFormat(area[0])+" "+OutFormat.doubleFormat(area[1])); 86 } 87 }break; 88 } 89 90 if(n!=0) { 91 if(!a.isTriangle()) { 92 System.out.println("not a quadrilateral or triangle"); 93 System.exit(0); 94 } 95 if(a.judgeLineCoincide(l)) { 96 System.out.println("The line is coincide with one of the lines"); 97 System.exit(0); 98 } 99 System.out.print(a.getIntersections(l).size()); 100 if(a.getIntersections(l).size()==2) { 101 double[] area =a.calArea(a.getIntersections(l).get(0), a.getIntersections(l).get(1)); 102 System.out.println(" "+OutFormat.doubleFormat(area[0])+" "+OutFormat.doubleFormat(area[1])); 103 } 104 } 105 } 106 107 /* 108 * 5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形) 109 * 或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral, 110 * 若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle" 111 * "或者on the quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。 112 */ 113 public static void handle5(ArrayList<Point> ps) { 114 PointInputError.wrongNumberOfPoints(ps, 5); 115 int n = Judge.f(ps); 116 Triangle a = new Triangle(); 117 118 switch(n) { 119 case 1:a.setX(ps.get(2));a.setY(ps.get(3));a.setZ(ps.get(4));break; 120 case 2:a.setX(ps.get(1));a.setY(ps.get(3));a.setZ(ps.get(4));break; 121 case 3:a.setX(ps.get(1));a.setY(ps.get(2));a.setZ(ps.get(4));break; 122 case 4:a.setX(ps.get(1));a.setY(ps.get(2));a.setZ(ps.get(3));break; 123 case 0:{Quadrilateral q = new Quadrilateral(ps.get(1), ps.get(2), ps.get(3), ps.get(4)); 124 if(!q.isQuadrilateral()) { 125 System.out.println("not a quadrilateral or triangle"); 126 System.exit(0); 127 } 128 if(q.isQuadrilateral()) { 129 if(q.isInside(ps.get(0))==0) { 130 System.out.println("on the quadrilateral"); 131 return ; 132 } 133 if(q.isInside(ps.get(0))==-1) { 134 System.out.println("outof the quadrilateral"); 135 return ; 136 } 137 System.out.println("in the quadrilateral"); 138 } 139 }break; 140 } 141 if(n!=0) { 142 if(!a.isTriangle()) { 143 System.out.println("not a quadrilateral or triangle"); 144 return ; 145 } 146 else { 147 if(a.isInside(ps.get(0))==0) { 148 System.out.println("on the triangle"); 149 return ; 150 } 151 if(a.isInside(ps.get(0))==-1) { 152 System.out.println("outof the triangle"); 153 return ; 154 } 155 System.out.println("in the triangle"); 156 } 157 } 158 } 159 } 160 161 class InputData { 162 private int choice;;//用户输入的选择项 163 private ArrayList<Point> points = new ArrayList<Point>();//用户输入的点坐标 164 public int getChoice() { 165 return choice; 166 } 167 public void setChoice(int choice) { 168 this.choice = choice; 169 } 170 public ArrayList<Point> getPoints() { 171 return points; 172 } 173 public void addPoint(Point p) { 174 this.points.add(p); 175 } 176 177 } 178 179 class Judge { 180 /* 181 * 输入:用户输入点集 182 * 返回:1:2 3 4构成三角形,2:1 3 4构成三角形,3:1 2 4构成三角形,4:1 2 3构成三角形,0:四个点不构成三角形 183 */ 184 public static int f(ArrayList<Point> ps){ 185 // 判断四个点是否构成三角形 186 if(ps.size()==5) { 187 Line L1 = new Line(ps.get(2), ps.get(4));//第二个点与第四个点构成的直线 188 Line L2 = new Line(ps.get(1), ps.get(3));//第一个点与第三个点构成的直线 189 190 if(L1.isBetween(ps.get(1))&& !L1.isBetween(ps.get(3))|| ps.get(1).isCoincide(ps.get(2))|| ps.get(1).isCoincide(ps.get(4))) { 191 return 1; 192 } 193 else if(L2.isBetween(ps.get(2))&& !L2.isBetween(ps.get(4))|| ps.get(2).isCoincide(ps.get(1))|| ps.get(2).isCoincide(ps.get(3))) { 194 return 2; 195 } 196 else if(L1.isBetween(ps.get(3))&& !L1.isBetween(ps.get(1))|| ps.get(3).isCoincide(ps.get(2))|| ps.get(3).isCoincide(ps.get(4))) { 197 return 3; 198 } 199 else if(L2.isBetween(ps.get(4))&& !L2.isBetween(ps.get(2))|| ps.get(4).isCoincide(ps.get(1))|| ps.get(4).isCoincide(ps.get(3))) { 200 return 4; 201 } 202 else 203 return 0; 204 } 205 else { 206 Line L1 = new Line(ps.get(2), ps.get(4));//第二个点与第四个点构成的直线 207 Line L2 = new Line(ps.get(3), ps.get(5));//第一个点与第三个点构成的直线 208 209 if(L2.isBetween(ps.get(2))&& !L2.isBetween(ps.get(4))|| ps.get(2).isCoincide(ps.get(3))|| ps.get(2).isCoincide(ps.get(5))) { 210 return 1; 211 } 212 else if(L1.isBetween(ps.get(3))&& !L1.isBetween(ps.get(5))|| ps.get(3).isCoincide(ps.get(2))|| ps.get(3).isCoincide(ps.get(4))) { 213 return 2; 214 } 215 else if(L2.isBetween(ps.get(4))&& !L2.isBetween(ps.get(2))|| ps.get(4).isCoincide(ps.get(3))|| ps.get(4).isCoincide(ps.get(5))) { 216 return 3; 217 } 218 else if(L1.isBetween(ps.get(5))&& !L1.isBetween(ps.get(3))|| ps.get(5).isCoincide(ps.get(2))|| ps.get(5).isCoincide(ps.get(4))) { 219 return 4; 220 } 221 else 222 return 0; 223 } 224 } 225 } 226 227 class Line { 228 private Point p1;//线上的第一个点 229 private Point p2;//线上的第二个点 230 231 232 public Line(double x1, double y1, double x2, double y2) { 233 Point p1 = new Point(x1, y1); 234 Point p2 = new Point(x2, y2); 235 LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出 236 this.p1 = p1; 237 this.p2 = p2; 238 } 239 240 public Line(Point p1, Point p2) { 241 LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出 242 this.p1 = p1; 243 this.p2 = p2; 244 } 245 246 /* 获取线条的斜率 */ 247 public Double getSlope() { 248 // (x1-x2=0)注意考虑斜率不存在即返回double类型无穷大"Infinite" 249 return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX()); 250 } 251 252 /* 判断x是否在线上 */ 253 public boolean isOnline(Point x) { 254 //System.out.println("isOnline"); 255 //System.out.println(p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y + " "); 256 257 // 点重合 258 if ((x.getX() == p1.getX() && x.getY() == p1.getY()) || (x.getX() == p2.getX() && x.getY() == p2.getY())) { 259 return true; 260 } 261 Line l = new Line(p1, x); 262 if (l.getSlope().isInfinite() && this.getSlope().isInfinite()) { 263 return true; 264 } 265 266 double b1 = l.getSlope(), b2 = this.getSlope(); 267 268 return Math.abs(b1 - b2) < 0.00000000001;// b1==b2; 269 } 270 271 public double getDistance(Point x) { 272 double distY = p2.getY() - p1.getY(); 273 double distX = p2.getX() - p1.getX(); 274 return Math.abs(x.getX() * distY - x.getY() * distX - p1.getX() * distY + p1.getY() * distX) 275 / p1.getDistance(p2); 276 } 277 278 public boolean isBetween(Point x) { 279 if (!this.isOnline(x)) { 280 return false; 281 } 282 if (x.equals(p1) || x.equals(p2)) { 283 return false; 284 } 285 double d = p2.getDistance(p1); 286 boolean b = x.getDistance(p2) < d && x.getDistance(p1) < d; 287 return b; 288 } 289 290 public boolean isSameSide(Point x) { 291 return isOnline(x) && !isBetween(x); 292 } 293 294 public Point getMiddlePoint() { 295 Point p = new Point(); 296 p.setX((p1.getX() + p2.getX()) / 2); 297 p.setY((p1.getY() + p2.getY()) / 2); 298 return p; 299 } 300 301 public Point getPointA() { 302 return p1; 303 } 304 305 public Point getPointB() { 306 return p2; 307 } 308 309 public double getAngle(Line l) { 310 double k2 = getSlope(); 311 double k1 = l.getSlope(); 312 return (double) (Math.atan(Math.abs((k2 - k1) / (1 + k1 * k2))) * 180.0 / Math.PI);// 返回值为角度 313 } 314 315 public boolean isParallel(Line l) { 316 Double b1 = this.getSlope(); 317 Double b2 = l.getSlope(); 318 if ((b1.isInfinite()) && (b2.isInfinite())) { 319 return true; 320 } else { 321 return (this.getSlope().doubleValue() == l.getSlope().doubleValue()); 322 } 323 } 324 325 326 public boolean isCoincide(Line l) { 327 if (!this.isParallel(l)) { 328 return false; 329 } 330 if (this.isOnline(l.p1)) { 331 return true; 332 } 333 return false; 334 } 335 336 public Point getIntersection(Line l) { 337 if (this.isParallel(l)) { 338 return null; 339 } 340 if (p1.equals(l.p1) || p1.equals(l.p2)) { 341 return p1; 342 } 343 if (p2.equals(l.p1) || p2.equals(l.p2)) { 344 return p2; 345 } 346 Point p3 = l.p1, p4 = l.p2; 347 double x_member, x_denominator, y_member, y_denominator; 348 Point cross_point = new Point(); 349 x_denominator = p4.x * p2.y - p4.x * p1.y - p3.x * p2.y + p3.x * p1.y - p2.x * p4.y + p2.x * p3.y + p1.x * p4.y 350 - p1.x * p3.y; 351 352 x_member = p3.y * p4.x * p2.x - p4.y * p3.x * p2.x - p3.y * p4.x * p1.x + p4.y * p3.x * p1.x 353 - p1.y * p2.x * p4.x + p2.y * p1.x * p4.x + p1.y * p2.x * p3.x - p2.y * p1.x * p3.x; 354 355 if (x_denominator == 0) 356 cross_point.x = 0; 357 else 358 cross_point.x = x_member / x_denominator; 359 360 y_denominator = p4.y * p2.x - p4.y * p1.x - p3.y * p2.x + p1.x * p3.y - p2.y * p4.x + p2.y * p3.x + p1.y * p4.x 361 - p1.y * p3.x; 362 363 y_member = -p3.y * p4.x * p2.y + p4.y * p3.x * p2.y + p3.y * p4.x * p1.y - p4.y * p3.x * p1.y 364 + p1.y * p2.x * p4.y - p1.y * p2.x * p3.y - p2.y * p1.x * p4.y + p2.y * p1.x * p3.y; 365 366 if (y_denominator == 0) 367 cross_point.y = 0; 368 else 369 cross_point.y = y_member / y_denominator; 370 371 // System.out.println(cross_point.x + ","+cross_point.y); 372 373 return cross_point; // 平行返回(0,0) 374 } 375 } 376 377 class LineInputError { 378 379 // 直线的两点重合的错误判断和提示。 380 public static void pointsCoincideError(Point p1, Point p2) { 381 if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) { 382 System.out.println("points coincide"); 383 System.exit(0); 384 } 385 } 386 387 } 388 389 class OutFormat { 390 //按要求格式化实数的输出。 391 public static Double doubleFormat(double b) { 392 DecimalFormat df = new DecimalFormat("#.000"); 393 Double output = Double.valueOf(df.format(b)); 394 return output; 395 } 396 } 397 398 class ParseInput { 399 public static void paseInput(String s, InputData d) { 400 PointInputError.wrongChoice(s); 401 d.setChoice(getChoice(s)); 402 s = s.substring(2); 403 pasePoints(s, d); 404 } 405 //获取输入字符串(格式:“选项:点坐标”)中选项部分 406 public static int getChoice(String s) { 407 char c = s.charAt(0); 408 return c-48; 409 } 410 public static void pasePoints(String s, InputData d) { 411 String[] ss = s.split(" "); 412 if (ss.length == 0) 413 return; 414 for (int i = 0; i < ss.length; i++) { 415 d.addPoint(readPoint(ss[i])); 416 } 417 } 418 419 public static Point readPoint(String s) { 420 PointInputError.wrongPointFormat(s); 421 String[] ss = s.split(","); 422 double x = Double.parseDouble(ss[0]); 423 double y = Double.parseDouble(ss[1]); 424 // System.out.println("match"); 425 return new Point(x, y); 426 427 } 428 } 429 430 class Point { 431 public double x; 432 public double y; 433 434 public Point() { 435 436 } 437 438 public Point(double x,double y) { 439 this.x=x; 440 this.y=y; 441 } 442 443 /* 设置坐标x,将输入参数赋值给属性x */ 444 public void setX(double x) { 445 this.x = x; 446 } 447 448 /* 设置坐标y,将输入参数赋值给属性y */ 449 public void setY(double y) { 450 this.y = y; 451 } 452 453 /* 获取坐标x,返回属性x的值 */ 454 public double getX() { 455 return x; 456 } 457 458 /* 获取坐标y,返回属性y的值 */ 459 public double getY() { 460 return y; 461 } 462 //判断两点是否重合 463 public boolean equals(Point p) { 464 boolean b = false; 465 if(this.x==p.getX()&&this.y==p.getY()) { 466 b=true; 467 } 468 return b; 469 } 470 471 /* 计算当前点和输入点p之间的距离 */ 472 public double getDistance(Point p) { 473 return Math.sqrt(Math.pow(this.x-p.x, 2)+ Math.pow(this.y-p.y, 2)); 474 } 475 476 /* 判断当前点和输入点p是否重合 */ 477 public boolean isCoincide(Point p) { 478 return this.x == p.x&& this.y == p.y; 479 } 480 } 481 482 class PointInputError { 483 //判断从字符串中解析出的点的数量是否合格。 484 public static void wrongNumberOfPoints(ArrayList<Point> ps, int num) { 485 if (ps.size() != num) { 486 System.out.println("wrong number of points"); 487 System.exit(0); 488 } 489 } 490 //判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序 491 public static void wrongPointFormat(String s) { 492 if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) { 493 System.out.println("Wrong Format"); 494 System.exit(0); 495 } 496 } 497 498 // 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一 499 public static void wrongChoice(String s) { 500 if (!s.matches("[1-5]:.+")) { 501 System.out.println("Wrong Format"); 502 System.exit(0); 503 } 504 } 505 506 } 507 508 class Quadrilateral { 509 private Point p1; 510 private Point p2; 511 private Point p3; 512 private Point p4; 513 private Line l1; 514 private Line l2; 515 private Line l3; 516 private Line l4; 517 518 public Quadrilateral(Point p1, Point p2, Point p3, Point p4) { 519 520 this.p1 = p1; 521 this.p2 = p2; 522 this.p3 = p3; 523 this.p4 = p4; 524 this.l1 = new Line(p1, p2); 525 this.l2 = new Line(p2, p3); 526 this.l3 = new Line(p3, p4); 527 this.l4 = new Line(p4, p1); 528 } 529 530 public Quadrilateral() { 531 } 532 533 public boolean isQuadrilateral() { 534 // 判断是否构成四边形 535 if(l1.isParallel(l2)|| l1.isParallel(l4)|| l3.isParallel(l2)|| l3.isParallel(l4)) 536 return false; 537 else if(l1.getIntersection(l3)!=null) { 538 if(l1.isBetween(l1.getIntersection(l3))&& l3.isBetween(l1.getIntersection(l3))) { 539 return false; 540 } 541 else { 542 return true; 543 } 544 } 545 else if(l2.getIntersection(l4)!=null) { 546 if(l2.isBetween(l2.getIntersection(l4))&& l4.isBetween(l2.getIntersection(l4))) { 547 return false; 548 } 549 else { 550 return true; 551 } 552 } 553 else 554 return true; 555 } 556 557 public boolean isParallelogram() { 558 // 判断四边形是否为平行四边形 559 if(p1.getDistance(p2) == p3.getDistance(p4)&& p2.getDistance(p3) == p1.getDistance(p4)) { 560 return true; 561 } 562 else 563 return false; 564 } 565 566 public boolean isDiamond() { 567 // 判断菱形 568 if(isParallelogram()) { 569 if(p1.getDistance(p2) == p2.getDistance(p3)) 570 return true; 571 else 572 return false; 573 } 574 else 575 return false; 576 } 577 578 public boolean isDectangle() { 579 // 判断四边形是否为矩形 580 if(isParallelogram()) { 581 if(p1.getDistance(p3) == p2.getDistance(p4)) 582 return true; 583 else 584 return false; 585 } 586 else 587 return false; 588 } 589 590 public boolean isSquare() { 591 // 正方形即为菱形和矩形 592 if(isDiamond()&& isDectangle()) 593 return true; 594 else 595 return false; 596 } 597 598 public boolean isConcave() { 599 // 判断四边形是否为凸四边形 600 Triangle a = new Triangle(p1,p2,p3); 601 Triangle b = new Triangle(p3,p4,p1); 602 Triangle c = new Triangle(p2,p3,p4); 603 Triangle d = new Triangle(p4,p1,p2); 604 if((a.getArea() + b.getArea()) == (c.getArea() + d.getArea())) 605 return true; 606 else 607 return false; 608 } 609 610 public double getPerimeter() { 611 // 获取四边形的周长 612 return p1.getDistance(p2)+p2.getDistance(p3)+p3.getDistance(p4)+p4.getDistance(p1); 613 } 614 615 public double getArea() { 616 // 获取四边形面积 617 Line[] ls = getSideline(); 618 Point x = new Point(ls[0].getMiddlePoint().x, ls[0].getMiddlePoint().y); 619 Point y = new Point(ls[2].getMiddlePoint().x, ls[2].getMiddlePoint().y); 620 Point z = new Point(ls[1].getMiddlePoint().x, ls[1].getMiddlePoint().y); 621 Line l = new Line(x, y); 622 return (double)2 * l.getDistance(z) * x.getDistance(y); 623 } 624 625 public Line[] getSideline() { 626 // 获取四条线 627 Line l1 = new Line(p1, p2); 628 Line l2 = new Line(p2, p3); 629 Line l3 = new Line(p3, p4); 630 Line l4 = new Line(p4, p1); 631 Line[] lines = { l1, l2, l3, l4 }; 632 return lines; 633 } 634 public int isInside(Point p) { 635 if (this.isOnTheEdge(p)) { 636 return 0; 637 } 638 if (isVertex(p)) { 639 return 0; 640 } 641 Triangle a =new Triangle(p, p1, p2); 642 Triangle b =new Triangle(p, p2, p3); 643 Triangle c =new Triangle(p, p3, p4); 644 Triangle d =new Triangle(p, p1, p4); 645 646 if(Math.abs(this.getArea() - a.getArea()-b.getArea()-c.getArea()-d.getArea() )< 1E-10) { 647 return 1; 648 } 649 if(this.getArea() < a.getArea()+b.getArea()+c.getArea()+d.getArea()) { 650 return -1; 651 } 652 return 0; 653 } 654 655 private boolean isVertex(Point p) { 656 return p.equals(p1) || p.equals(p2) || p.equals(p3) || p.equals(p4); 657 } 658 659 private boolean isOnTheEdge(Point p) { 660 if(l1.isBetween(p)|| l2.isBetween(p)|| l3.isBetween(p)|| l4.isBetween(p)) 661 return true; 662 else 663 return false; 664 } 665 666 public ArrayList<Point> getIntersections(Line l) { 667 ArrayList<Point> ps = new ArrayList<Point>(); 668 Line[] ls = getSideline(); 669 if(!judgeLineCoincide(l)) { 670 if(l.isOnline(p1)) 671 ps.add(p1); 672 if(l.isOnline(p2)) 673 ps.add(p2); 674 if(l.isOnline(p3)) 675 ps.add(p3); 676 if(l.isOnline(p4)) 677 ps.add(p4); 678 if(l.getIntersection(ls[0])!=null) { 679 if(ls[0].isBetween(l.getIntersection(ls[0]))) { 680 ps.add(l.getIntersection(ls[0])); 681 } 682 } 683 if(l.getIntersection(ls[1])!=null) { 684 if(ls[1].isBetween(l.getIntersection(ls[1]))) { 685 ps.add(l.getIntersection(ls[1])); 686 } 687 } 688 if(l.getIntersection(ls[2])!=null) { 689 if(ls[2].isBetween(l.getIntersection(ls[2]))) { 690 ps.add(l.getIntersection(ls[2])); 691 } 692 } 693 if(l.getIntersection(ls[3])!=null) { 694 if(ls[3].isBetween(l.getIntersection(ls[3]))) { 695 ps.add(l.getIntersection(ls[3])); 696 } 697 } 698 } 699 return ps; 700 } 701 public double[] calArea(Point p1, Point p2) { 702 Line[] ls = getSideline(); 703 Triangle t = new Triangle(); 704 Quadrilateral q = new Quadrilateral(); 705 if(this.isVertex(p1)) { 706 if(p1.equals(this.p1)) { 707 if(ls[1].isBetween(p2)) { 708 t.setX(p1);t.setY(this.p2);t.setZ(p2); 709 } 710 else { 711 t.setX(p1);t.setY(this.p4);t.setZ(p2); 712 } 713 } 714 else if(p1.equals(this.p2)) { 715 if(ls[2].isBetween(p2)) { 716 t.setX(p1);t.setY(this.p3);t.setZ(p2); 717 } 718 else { 719 t.setX(p1);t.setY(this.p1);t.setZ(p2); 720 } 721 } 722 else if(p1.equals(this.p3)){ 723 if(ls[0].isBetween(p2)) { 724 t.setX(p1);t.setY(this.p2);t.setZ(p2); 725 } 726 else { 727 t.setX(p1);t.setY(this.p4);t.setZ(p2); 728 } 729 } 730 else if(p1.equals(this.p4)){ 731 if(ls[0].isBetween(p2)) { 732 t.setX(p1);t.setY(this.p1);t.setZ(p2); 733 } 734 else { 735 t.setX(p1);t.setY(this.p3);t.setZ(p2); 736 } 737 } 738 } 739 else { 740 if((ls[0].isBetween(p1) && ls[1].isBetween(p2)) || (ls[0].isBetween(p2) && ls[1].isBetween(p1))) { 741 t.setX(p1);t.setY(this.p2);t.setZ(p2); 742 } 743 if((ls[0].isBetween(p1) && ls[2].isBetween(p2)) || (ls[0].isBetween(p2) && ls[2].isBetween(p1))) { 744 q.setP1(p1);q.setP2(this.p2);q.setP3(this.p3);q.setP4(p2); 745 } 746 if((ls[0].isBetween(p1) && ls[3].isBetween(p2)) || (ls[0].isBetween(p2) && ls[3].isBetween(p1))) { 747 t.setX(p1);t.setY(this.p1);t.setZ(p2); 748 } 749 if((ls[1].isBetween(p1) && ls[2].isBetween(p2)) || (ls[1].isBetween(p2) && ls[2].isBetween(p1))) { 750 t.setX(p1);t.setY(this.p3);t.setZ(p2); 751 } 752 if((ls[1].isBetween(p1) && ls[3].isBetween(p2)) || (ls[1].isBetween(p2) && ls[3].isBetween(p1))) { 753 q.setP1(p1);q.setP2(this.p3);q.setP3(this.p4);q.setP4(p2); 754 } 755 if((ls[2].isBetween(p1) && ls[3].isBetween(p2)) || (ls[2].isBetween(p2) && ls[3].isBetween(p1))) { 756 t.setX(p1);t.setY(this.p4);t.setZ(p2); 757 } 758 } 759 if(t.getX()!=null) { 760 double[] area = {t.getArea(),this.calAreaDiffrence(t)}; 761 if(area[0]>area[1]) { 762 double temp; 763 temp=area[0]; 764 area[0]=area[1]; 765 area[1]=temp; 766 } 767 return area; 768 } 769 else { 770 double[] area = {q.getArea(),this.calAreaDiffrence(q)}; 771 if(area[0]>area[1]) { 772 double temp; 773 temp=area[0]; 774 area[0]=area[1]; 775 area[1]=temp; 776 } 777 return area; 778 } 779 } 780 781 private double calAreaDiffrence(Triangle t) { 782 double area = t.getArea(); 783 area = getArea() - area; 784 return area; 785 } 786 787 private double calAreaDiffrence(Quadrilateral q) { 788 double area = q.getArea(); 789 area = getArea() - area; 790 return area; 791 } 792 793 public boolean judgeLineCoincide(Line l) { 794 if(l.isCoincide(l1)|| l.isCoincide(l2)|| l.isCoincide(l3)|| l.isCoincide(l4)) 795 return true; 796 else 797 return false; 798 } 799 800 public void setP1(Point p1) { 801 this.p1 = p1; 802 } 803 804 public void setP2(Point p2) { 805 this.p2 = p2; 806 } 807 808 public void setP3(Point p3) { 809 this.p3 = p3; 810 } 811 812 public void setP4(Point p4) { 813 this.p4 = p4; 814 } 815 816 } 817 818 class Triangle { 819 private Point x; 820 private Point y; 821 private Point z; 822 823 public Triangle(Point x, Point y, Point z) { 824 this.x = x; 825 this.y = y; 826 this.z = z; 827 828 } 829 830 public Triangle() { 831 } 832 833 public boolean isTriangle() { 834 if(x.getDistance(y)+ x.getDistance(z)> y.getDistance(z) 835 && y.getDistance(z)+ y.getDistance(x)> x.getDistance(z) 836 && z.getDistance(x)+ z.getDistance(y)> x.getDistance(y)) 837 return true; 838 else 839 return false; 840 841 } 842 843 public Point getMidpoint() { 844 // 中点即重心,利用性质求解 845 Point p = new Point(); 846 p.setX((this.x.getX() + this.y.getX() + this.z.getX()) / 3); 847 p.setY((this.x.getY() + this.y.getY() + this.z.getY()) / 3); 848 return p; 849 } 850 851 public Line[] getSideline() { 852 Line line1 = new Line(x, y); 853 854 Line line2 = new Line(x, z); 855 Line line3 = new Line(y, z); 856 857 Line[] lines = { line1, line2, line3 }; 858 return lines; 859 } 860 861 public double getArea() { 862 double p = (x.getDistance(y)+ x.getDistance(z)+ y.getDistance(z))/2; 863 return Math.sqrt(p* (p- x.getDistance(y))* (p-x.getDistance(z))* (p-y.getDistance(z))); 864 } 865 866 public double getPerimeter() { 867 return x.getDistance(y) + y.getDistance(z) + z.getDistance(x); 868 } 869 870 public boolean isVertex(Point p) { 871 return p.equals(x) || p.equals(y) || p.equals(z); 872 } 873 874 public int isInside(Point p) { 875 if (this.isOnTheEdge(p)) { 876 return 0; 877 } 878 if (isVertex(p)) { 879 return 0; 880 } 881 Triangle a = new Triangle(p, x, y); 882 Triangle b = new Triangle(p, x, z); 883 Triangle c = new Triangle(p, z, y); 884 if(Math.abs(this.getArea() - a.getArea()-b.getArea()-c.getArea()) <1E-10) { 885 return 1; 886 } 887 if(this.getArea() < a.getArea()+b.getArea()+c.getArea()) { 888 return -1; 889 } 890 return 0; 891 } 892 893 public ArrayList<Point> getIntersections(Line l) { 894 ArrayList<Point> ps = new ArrayList<Point>(); 895 Line[] ls = getSideline(); 896 if(!judgeLineCoincide(l)) { 897 if(l.isOnline(x)) 898 ps.add(x); 899 if(l.isOnline(y)) 900 ps.add(y); 901 if(l.isOnline(z)) 902 ps.add(z); 903 if(l.getIntersection(ls[0])!=null) { 904 if(ls[0].isBetween(l.getIntersection(ls[0]))) { 905 ps.add(l.getIntersection(ls[0])); 906 } 907 } 908 if(l.getIntersection(ls[1])!=null) { 909 if(ls[1].isBetween(l.getIntersection(ls[1]))) { 910 ps.add(l.getIntersection(ls[1])); 911 } 912 } 913 if(l.getIntersection(ls[2])!=null) { 914 if(ls[2].isBetween(l.getIntersection(ls[2]))) { 915 ps.add(l.getIntersection(ls[2])); 916 } 917 } 918 } 919 return ps; 920 } 921 922 923 public double[] calArea(Point p1, Point p2) { 924 Line[] l= getSideline(); 925 Triangle t = new Triangle(); 926 if(this.isVertex(p1)) { 927 if(p1.equals(x)) { 928 t.setX(p1);t.setY(p2);t.setZ(y); 929 } 930 else if(p1.equals(y)) { 931 t.setX(p1);t.setY(p2);t.setZ(z); 932 } 933 else { 934 t.setX(p1);t.setY(p2);t.setZ(x); 935 } 936 } 937 else { 938 if((l[0].isBetween(p1)&& l[1].isBetween(p2)) 939 || (l[0].isBetween(p1)&& l[1].isBetween(p2))){ 940 t.setX(p1);t.setY(p2);t.setZ(y); 941 } 942 if((l[1].isBetween(p1)&& l[2].isBetween(p2)) 943 || (l[1].isBetween(p1)&& l[2].isBetween(p2))){ 944 t.setX(p1);t.setY(p2);t.setZ(z); 945 } 946 if((l[0].isBetween(p1)&& l[2].isBetween(p2)) 947 || (l[0].isBetween(p1)&& l[2].isBetween(p2))){ 948 t = new Triangle(p1, p2, x); 949 } 950 } 951 double[] area = {t.getArea(),this.calAreaDiffrence(t)}; 952 if(area[0]>area[1]) { 953 double temp; 954 temp=area[0]; 955 area[0]=area[1]; 956 area[1]=temp; 957 } 958 return area; 959 } 960 961 962 963 public double calAreaDiffrence(Triangle t1) { 964 double area = t1.getArea(); 965 area = getArea() - area; 966 return area; 967 } 968 969 public boolean judgeLineCoincide(Line l) { 970 Line[] ls = getSideline(); 971 if(l.isCoincide(ls[0])|| l.isCoincide(ls[1])|| l.isCoincide(ls[2])) 972 return true; 973 else 974 return false; 975 } 976 977 public boolean isOnTheEdge(Point p) { 978 Line[] l = getSideline(); 979 if(l[0].isBetween(p)|| l[1].isBetween(p)|| l[2].isBetween(p)) 980 return true; 981 else 982 return false; 983 } 984 985 public Point getX() { 986 return x; 987 } 988 989 public void setX(Point x) { 990 this.x = x; 991 } 992 993 public Point getY() { 994 return y; 995 } 996 997 public void setY(Point y) { 998 this.y = y; 999 } 1000 1001 public Point getZ() { 1002 return z; 1003 } 1004 1005 public void setZ(Point z) { 1006 this.z = z; 1007 } 1008 }
2.期中考试
7-1 点与线
(1)类图
(2)圈复杂度
(3)解释
此题比较简单跟着题目类图和提示走,基本能完成。
(4)心得
根据题目提示了解到String.format("%.2f", data)格式化输出,更加了解使用Math类方法。
(5)整题源码

1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 double a,b,c,d; 7 Scanner in = new Scanner(System.in); 8 a = in.nextDouble(); 9 b = in.nextDouble(); 10 c = in.nextDouble(); 11 d = in.nextDouble(); 12 String color = in.next(); 13 if(a<=0 || a>200 || b<=0 || b>200 || c<=0 || c>200 ||d<=0 || d>200 ) { 14 System.out.println("Wrong Format"); 15 System.exit(0); 16 } 17 Point p1 = new Point(a, b); 18 Point p2 = new Point(c, d); 19 Line l = new Line(p1, p2, color); 20 l.display(); 21 System.out.println("The line's begin point's Coordinate is:"); 22 p1.dsiplay(); 23 System.out.println("The line's end point's Coordinate is:"); 24 p2.dsiplay(); 25 System.out.println("The line's length is:"+String.format("%.2f", l.getDistance())); 26 } 27 28 } 29 30 class Point { 31 private double x; 32 private double y; 33 34 public Point(double x, double y) { 35 this.x = x; 36 this.y = y; 37 } 38 39 public Point() { 40 41 } 42 43 public double getX() { 44 return x; 45 } 46 47 public void setX(double x) { 48 this.x = x; 49 } 50 51 public double getY() { 52 return y; 53 } 54 55 public void setY(double y) { 56 this.y = y; 57 } 58 59 public void dsiplay() { 60 System.out.println("("+String.format("%.2f", this.x)+","+String.format("%.2f", this.y)+")"); 61 } 62 63 } 64 65 class Line { 66 private Point point1; 67 private Point point2; 68 private String color; 69 70 public Line() { 71 72 } 73 74 public Line(Point point1, Point point2, String color) { 75 this.point1 = point1; 76 this.point2 = point2; 77 this.color = color; 78 } 79 80 public Point getPoint1() { 81 return point1; 82 } 83 84 public void setPoint1(Point point1) { 85 this.point1 = point1; 86 } 87 88 public Point getPoint2() { 89 return point2; 90 } 91 92 public void setPoint2(Point point2) { 93 this.point2 = point2; 94 } 95 96 public String getColor() { 97 return color; 98 } 99 100 public void setColor(String color) { 101 this.color = color; 102 } 103 104 public void display() { 105 System.out.println("The line's color is:"+this.color); 106 } 107 108 public double getDistance() { 109 return Math.sqrt(Math.pow(point1.getX() - point2.getX(), 2) + Math.pow(point1.getY() - point2.getY(), 2)); 110 } 111 112 }
7-2 点线面问题重构(继承与多态)
(1)类图
(2)圈复杂度
(3)解释
此题当时考试前没接触过抽象接口,所以不知道abstract是什么,就没有把Element类设计成抽象类。Point,Line,Plane类继承与Element类。Main类复杂度过高是因为控制题目输入的时候选择语句过多。

1 if(a<=0 || a>200 || b<=0 || b>200 || c<=0 || c>200 ||d<=0 || d>200 ) { 2 System.out.println("Wrong Format"); 3 System.exit(0); 4 }
(4)心得
此题让我了解到了继承的魅力,为第五次的题目集打下很好的基础,题目中老师的一部分示例代码也让我知道父类对象的用法。
(5)整题源码

1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 double a,b,c,d; 7 Scanner in = new Scanner(System.in); 8 a = in.nextDouble(); 9 b = in.nextDouble(); 10 c = in.nextDouble(); 11 d = in.nextDouble(); 12 String color = in.next(); 13 if(a<=0 || a>200 || b<=0 || b>200 || c<=0 || c>200 ||d<=0 || d>200 ) { 14 System.out.println("Wrong Format"); 15 System.exit(0); 16 } 17 Point p1 = new Point(a, b); 18 Point p2 = new Point(c, d); 19 Line line = new Line(p1, p2, color); 20 Plane plane = new Plane(color); 21 Element element = new Element(); 22 element = p1;//起点Point 23 element.display(); 24 25 element = p2;//终点Point 26 element.display(); 27 28 element = line;//线段 29 element.display(); 30 31 element = plane;//面 32 element.display(); 33 34 } 35 36 } 37 38 class Point extends Element{ 39 private double x; 40 private double y; 41 42 public Point(double x, double y) { 43 this.x = x; 44 this.y = y; 45 } 46 47 public Point() { 48 49 } 50 51 public double getX() { 52 return x; 53 } 54 55 public void setX(double x) { 56 this.x = x; 57 } 58 59 public double getY() { 60 return y; 61 } 62 63 public void setY(double y) { 64 this.y = y; 65 } 66 @Override 67 public void display() { 68 System.out.println("("+String.format("%.2f", this.x)+","+String.format("%.2f", this.y)+")"); 69 } 70 71 } 72 73 class Line extends Element{ 74 private Point point1; 75 private Point point2; 76 private String color; 77 public Line() { 78 79 } 80 81 public Line(Point point1, Point point2, String color) { 82 this.point1 = point1; 83 this.point2 = point2; 84 this.color = color; 85 } 86 87 public Point getPoint1() { 88 return point1; 89 } 90 91 public void setPoint1(Point point1) { 92 this.point1 = point1; 93 } 94 95 public Point getPoint2() { 96 return point2; 97 } 98 99 public void setPoint2(Point point2) { 100 this.point2 = point2; 101 } 102 103 public String getColor() { 104 return color; 105 } 106 107 public void setColor(String color) { 108 this.color = color; 109 } 110 @Override 111 public void display() { 112 System.out.println("The line's color is:"+this.color); 113 System.out.println("The line's begin point's Coordinate is:"); 114 getPoint1().display(); 115 System.out.println("The line's end point's Coordinate is:"); 116 getPoint2().display(); 117 System.out.println("The line's length is:"+String.format("%.2f", getDistance()));; 118 } 119 120 public double getDistance() { 121 return Math.sqrt(Math.pow(point1.getX() - point2.getX(), 2) + Math.pow(point1.getY() - point2.getY(), 2)); 122 } 123 124 } 125 126 class Plane extends Element{ 127 private String color; 128 129 public Plane() { 130 131 } 132 133 public Plane(String color) { 134 super(); 135 this.color = color; 136 } 137 138 public String getColor() { 139 return color; 140 } 141 142 public void setColor(String color) { 143 this.color = color; 144 } 145 146 @Override 147 public void display() { 148 System.out.println("The Plane's color is:"+this.color); 149 } 150 } 151 152 class Element { 153 154 public void display() { 155 } 156 }
7-3 点线面问题再重构(容器类)
(1)类图
(2)圈复杂度
(3)解释
此题新加一个容器类,专门管理容器,而不是直接对容器进行操作。此题同样有一部分老师给的代码,方便了我们的编写。
(4)心得
此题亮眼的是新加的一个容器类,通过容器类的对象管理容器,这样可以大大降低程序出错的概率,也方便以后的修改。
1 public class GeometryObject { 2 private ArrayList<Element> es = new ArrayList<Element>(); 3 4 public GeometryObject() { 5 } 6 7 public void add(Element element) { 8 es.add(element); 9 } 10 11 public void remove(int index) { 12 if(index>=1 && index<=es.size()) 13 es.remove(index-1); 14 } 15 16 public ArrayList<Element> getEs() { 17 return es; 18 } 19 20 }
(5)整题码源

1 import java.util.ArrayList; 2 import java.util.Scanner; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 double a,b,c,d; 8 Scanner in = new Scanner(System.in); 9 GeometryObject g = new GeometryObject(); 10 int choice = in.nextInt(); 11 while(choice != 0) { 12 switch(choice) { 13 case 1://insert Point object into list 14 a = in.nextDouble(); 15 b = in.nextDouble(); 16 if(a<=0 || a>200 || b<=0 || b>200) { 17 System.out.println("Wrong Format"); 18 System.exit(0); 19 } 20 Point p1 = new Point(); 21 p1.setX(a);p1.setY(b); 22 g.add(p1); 23 break; 24 case 2://insert Line object into list 25 Line line = new Line(); 26 a = in.nextDouble(); 27 b = in.nextDouble(); 28 c = in.nextDouble(); 29 d = in.nextDouble(); 30 String color = in.next(); 31 if(a<=0 || a>200 || b<=0 || b>200 || c<=0 || c>200 || d<=0 || d>200) { 32 System.out.println("Wrong Format"); 33 System.exit(0); 34 } 35 Point p2 = new Point(a, b); 36 Point p3 = new Point(c, d); 37 line.setPoint1(p2);line.setPoint2(p3);line.setColor(color); 38 g.add(line); 39 break; 40 case 3://insert Plane object into list 41 Plane plane = new Plane(); 42 String co = in.next(); 43 plane.setColor(co); 44 g.add(plane); 45 break; 46 case 4://delete index - 1 object from list 47 int index = in.nextInt(); 48 g.remove(index); 49 } 50 choice = in.nextInt(); 51 } 52 for(Element e: g.getEs()) { 53 e.display(); 54 } 55 } 56 57 } 58 59 class Point extends Element{ 60 private double x; 61 private double y; 62 63 public Point(double x, double y) { 64 this.x = x; 65 this.y = y; 66 } 67 68 public Point() { 69 70 } 71 72 public double getX() { 73 return x; 74 } 75 76 public void setX(double x) { 77 this.x = x; 78 } 79 80 public double getY() { 81 return y; 82 } 83 84 public void setY(double y) { 85 this.y = y; 86 } 87 @Override 88 public void display() { 89 System.out.println("("+String.format("%.2f", this.x)+","+String.format("%.2f", this.y)+")"); 90 } 91 92 } 93 94 class Line extends Element{ 95 private Point point1; 96 private Point point2; 97 private String color; 98 public Line() { 99 100 } 101 102 public Line(Point point1, Point point2, String color) { 103 this.point1 = point1; 104 this.point2 = point2; 105 this.color = color; 106 } 107 108 public Point getPoint1() { 109 return point1; 110 } 111 112 public void setPoint1(Point point1) { 113 this.point1 = point1; 114 } 115 116 public Point getPoint2() { 117 return point2; 118 } 119 120 public void setPoint2(Point point2) { 121 this.point2 = point2; 122 } 123 124 public String getColor() { 125 return color; 126 } 127 128 public void setColor(String color) { 129 this.color = color; 130 } 131 @Override 132 public void display() { 133 System.out.println("The line's color is:"+this.color); 134 System.out.println("The line's begin point's Coordinate is:"); 135 getPoint1().display(); 136 System.out.println("The line's end point's Coordinate is:"); 137 getPoint2().display(); 138 System.out.println("The line's length is:"+String.format("%.2f", getDistance()));; 139 } 140 141 public double getDistance() { 142 return Math.sqrt(Math.pow(point1.getX() - point2.getX(), 2) + Math.pow(point1.getY() - point2.getY(), 2)); 143 } 144 145 } 146 147 class Plane extends Element{ 148 private String color; 149 150 public Plane() { 151 152 } 153 154 public Plane(String color) { 155 super(); 156 this.color = color; 157 } 158 159 public String getColor() { 160 return color; 161 } 162 163 public void setColor(String color) { 164 this.color = color; 165 } 166 167 @Override 168 public void display() { 169 System.out.println("The Plane's color is:"+this.color); 170 } 171 } 172 173 class Element { 174 175 public void display() { 176 } 177 } 178 179 class GeometryObject { 180 private ArrayList<Element> es = new ArrayList<Element>(); 181 182 public GeometryObject() { 183 } 184 185 public void add(Element element) { 186 es.add(element); 187 } 188 189 public void remove(int index) { 190 if(index>=1 && index<=es.size()) 191 es.remove(index-1); 192 } 193 194 public ArrayList<Element> getEs() { 195 return es; 196 } 197 198 }
3.第五次题目集
(1)类图
(2)圈复杂度
(3)解释
这里解释一下
1.对五边形面积的计算
读题后发现只需要求凸五边形的面积,所以这里直接将五边形直接分成了一个三角形和四边形计算面积;这里给出代码,至于三角形和四边形面积求法可查看上面代码

1 public double getArea() { 2 // 获取五边形面积 3 Triangle t = new Triangle(p1, p2, p3); 4 Quadrilateral q = new Quadrilateral(p3, p4, p5, p1); 5 return t.getArea() + q.getArea(); 6 }
2.对去除冗余点的方法
冗余点的判断只需判断是否有点在图形的对角线上,然后中间的点即为冗余点然后去除,这里分为两次来求,先对五个点进行一次冗余,在对四个点进行冗余点,然后根据返回点集长度判断是 否有冗余点,对上一次题目集方法进行改进。代码如下

1 public class Judge1 { 2 // 判断五个点构成五边形还是四边形 3 public static ArrayList<Point> f(ArrayList<Point> ps){ 4 ArrayList<Point> ps2 = new ArrayList<Point>(); 5 Line l1 = new Line(ps.get(0), ps.get(2)); 6 Line l2 = new Line(ps.get(0), ps.get(3)); 7 Line l3 = new Line(ps.get(1), ps.get(3)); 8 Line l4 = new Line(ps.get(1), ps.get(4)); 9 Line l5 = new Line(ps.get(2), ps.get(4)); 10 if(l1.isBetween(ps.get(1)) || ps.get(1).isCoincide(ps.get(0)) || ps.get(1).isCoincide(ps.get(2))) { 11 ps2.add(ps.get(0));ps2.add(ps.get(2));ps2.add(ps.get(3));ps2.add(ps.get(4)); 12 } 13 else if(l2.isBetween(ps.get(4)) || ps.get(4).isCoincide(ps.get(0)) || ps.get(4).isCoincide(ps.get(3))) { 14 ps2.add(ps.get(0));ps2.add(ps.get(1));ps2.add(ps.get(2));ps2.add(ps.get(3)); 15 } 16 else if(l3.isBetween(ps.get(2)) || ps.get(2).isCoincide(ps.get(1)) || ps.get(2).isCoincide(ps.get(3))) { 17 ps2.add(ps.get(0));ps2.add(ps.get(1));ps2.add(ps.get(3));ps2.add(ps.get(4)); 18 } 19 else if(l4.isBetween(ps.get(0)) || ps.get(0).isCoincide(ps.get(1)) || ps.get(0).isCoincide(ps.get(4))) { 20 ps2.add(ps.get(1));ps2.add(ps.get(2));ps2.add(ps.get(3));ps2.add(ps.get(4)); 21 } 22 else if(l5.isBetween(ps.get(3)) || ps.get(3).isCoincide(ps.get(2)) || ps.get(1).isCoincide(ps.get(4))) { 23 ps2.add(ps.get(0));ps2.add(ps.get(1));ps2.add(ps.get(2));ps2.add(ps.get(4)); 24 } 25 return ps2; 26 } 27 }

1 public class Judge { 2 /* 3 * 输入:用户输入四个点点集 4 * 返回:构成三角形的点集,若构成四边形,则返回点集size为0 5 */ 6 public static ArrayList<Point> f(ArrayList<Point> ps){ 7 // 判断四个点是否构成三角形 8 ArrayList<Point> ps1 =new ArrayList<Point>(); 9 Line l1 = new Line(ps.get(1), ps.get(3)); 10 Line l2 = new Line(ps.get(0), ps.get(2));//对角线 11 12 if(l1.isBetween(ps.get(0)) || ps.get(0).isCoincide(ps.get(1))|| ps.get(0).isCoincide(ps.get(3))) { 13 ps1.add(ps.get(1));ps1.add(ps.get(2));ps1.add(ps.get(3)); 14 } 15 else if(l2.isBetween(ps.get(1)) || ps.get(1).isCoincide(ps.get(0))|| ps.get(1).isCoincide(ps.get(2))) { 16 ps1.add(ps.get(0));ps1.add(ps.get(2));ps1.add(ps.get(3)); 17 } 18 else if(l1.isBetween(ps.get(2)) || ps.get(2).isCoincide(ps.get(1))|| ps.get(2).isCoincide(ps.get(3))) { 19 ps1.add(ps.get(0));ps1.add(ps.get(1));ps1.add(ps.get(3)); 20 } 21 else if(l2.isBetween(ps.get(3)) || ps.get(3).isCoincide(ps.get(0))|| ps.get(3).isCoincide(ps.get(2))) { 22 ps1.add(ps.get(0));ps1.add(ps.get(1));ps1.add(ps.get(2)); 23 } 24 return ps1; 25 } 26 }
3.对五边形凹凸的判断(向量叉乘的方法)
向量叉乘正负同号即为顺时针或者逆时针排列,即可判断为凸五边形(实则不止五边形,四边形即以上都可用)。代码如下

public boolean isTPentagon() { // 判断五边形凹凸性 Line[] ls = getSideline(); double v0 = ls[0].getchaji(ls[1]); double v1 = ls[1].getchaji(ls[2]); double v2 = ls[2].getchaji(ls[3]); double v3 = ls[3].getchaji(ls[4]); double v4 = ls[4].getchaji(ls[0]); if(v0 * v1 < 0 || v0 * v2 < 0 || v0 * v3 < 0 || v0 * v4 <0) { return false; } else return true; }
4.将点集中点顺时针化或逆时针化
通过对横坐标的比较和纵坐标的比较进行排序。代码如下

1 for (int i = 0; i <ps.size() - 1; i++) { 2 for (int j = 0; j < ps.size() - 1 - i; j++) { 3 if (SetSortRule(ps.get(j), ps.get(j+1))) { 4 double x=ps.get(j).getX(); 5 double y=ps.get(j).getY(); 6 ps.get(j).setX(ps.get(j+1).getX()); ps.get(j).setY(ps.get(j+1).getY()); 7 ps.get(j+1).setX(x);ps.get(j+1).setY(y); 8 } 9 } 10 } 11 return ps; 12 } 13 private boolean SetSortRule(Point p1, Point p2) { 14 if (p1.y > p2.y) { 15 return true; 16 } 17 else if (p1.y == p2.y) { 18 return (p1.x > p2.x); 19 } 20 else { 21 return false; 22 } 23 }
5.对任意凸多边形传入的顺时针或逆时针点集求面积的方法
根据面积公式。代码如下

public static double area(ArrayList<Point> ps) { int point_num = ps.size(); if(point_num < 3)return 0; double s = ps.get(0).y * (ps.get(point_num-1).x - ps.get(1).x); for(int i = 1; i < point_num; ++i) s += ps.get(i).y * (ps.get(i-1).x - ps.get((i+1)%point_num).x); return Math.abs(s/2.0); }
6.父类对象的使用
此题中的选项3、4、5、6中都创建了父类对象来代替子类操作,减少了代码量
(4)心得
对于此题,经过期中考试和实验,这题如果使用了继承多态是一个非常好的学习机会,大大减少代码量。在某些方面可以取巧,求五边形面积取巧,但后续可以改为通用的方法;学会了许多方法,判断点冗余、点集顺或逆时针化、点集构成多边形的面积、对容器的操作更加熟练。但在这段过程中最主要的还是学习到了Java的精髓--继承,方法覆盖,多态。
三、踩坑心得
1.第四次题目集中的判断冗余用的方法过于笨重,根据返回值来判断,后来改为根据返回点集判断,这样减少了代码量,也减小了圈复杂度。

public static ArrayList<Point> f(ArrayList<Point> ps){ // 判断四个点是否构成三角形 ArrayList<Point> ps1 =new ArrayList<Point>(); Line l1 = new Line(ps.get(1), ps.get(3)); Line l2 = new Line(ps.get(0), ps.get(2));//对角线 if(l1.isBetween(ps.get(0)) || ps.get(0).isCoincide(ps.get(1))|| ps.get(0).isCoincide(ps.get(3))) { ps1.add(ps.get(1));ps1.add(ps.get(2));ps1.add(ps.get(3)); } else if(l2.isBetween(ps.get(1)) || ps.get(1).isCoincide(ps.get(0))|| ps.get(1).isCoincide(ps.get(2))) { ps1.add(ps.get(0));ps1.add(ps.get(2));ps1.add(ps.get(3)); } else if(l1.isBetween(ps.get(2)) || ps.get(2).isCoincide(ps.get(1))|| ps.get(2).isCoincide(ps.get(3))) { ps1.add(ps.get(0));ps1.add(ps.get(1));ps1.add(ps.get(3)); } else if(l2.isBetween(ps.get(3)) || ps.get(3).isCoincide(ps.get(0))|| ps.get(3).isCoincide(ps.get(2))) { ps1.add(ps.get(0));ps1.add(ps.get(1));ps1.add(ps.get(2)); } return ps1; }
2.第四次中判断平行四边形开始使用一组对边平行且相等的方法判定,但是会导致漏情况,代码量也多。随后改为两组对边相等,完美解决这个问题。
3.第四次最后还有两个测试点没过,是因为三角形类中getsideline方法返回线数组不是按顺序来的,导致求三角形分为两个部分面积时出错。
4.第五次中的选项一中由于是输出TRUE或FALSE,但是当输入连续两个点重合时,构成线的地方会直接输出points coincide,并退出程序,所以在构造的地方加上判断。代码如下

public Pentagon(Point p1, Point p2, Point p3, Point p4, Point p5) { // 构造 super(); if(p1.equals(p2)||p1.equals(p3)||p1.equals(p4)||p1.equals(p5)||p2.equals(p3)||p2.equals(p4)||p2.equals(p5)||p3.equals(p4)||p3.equals(p5)||p4.equals(p5)) { System.out.println("false"); System.exit(0); } this.p1 = p1; this.p2 = p2; this.p3 = p3; this.p4 = p4; this.p5 = p5; }
5.第五次在判断两多边形重合时,输出结果少打了个with,检查很久才发现。还是要看清题目要求。
在许多地方代码复制时没有修改相应变化地方,同样导致要回头检查很久,还导致过不了测试点。double类型变量会有一定误差,要通过两个变量相见的绝对值判断是否相等。
四、改进建议
1.第四次中判断点冗余的方法改进。

1 public static ArrayList<Point> f(ArrayList<Point> ps){ 2 // 判断四个点是否构成三角形 3 ArrayList<Point> ps1 =new ArrayList<Point>(); 4 Line l1 = new Line(ps.get(1), ps.get(3)); 5 Line l2 = new Line(ps.get(0), ps.get(2));//对角线 6 7 if(l1.isBetween(ps.get(0)) || ps.get(0).isCoincide(ps.get(1))|| ps.get(0).isCoincide(ps.get(3))) { 8 ps1.add(ps.get(1));ps1.add(ps.get(2));ps1.add(ps.get(3)); 9 } 10 else if(l2.isBetween(ps.get(1)) || ps.get(1).isCoincide(ps.get(0))|| ps.get(1).isCoincide(ps.get(2))) { 11 ps1.add(ps.get(0));ps1.add(ps.get(2));ps1.add(ps.get(3)); 12 } 13 else if(l1.isBetween(ps.get(2)) || ps.get(2).isCoincide(ps.get(1))|| ps.get(2).isCoincide(ps.get(3))) { 14 ps1.add(ps.get(0));ps1.add(ps.get(1));ps1.add(ps.get(3)); 15 } 16 else if(l2.isBetween(ps.get(3)) || ps.get(3).isCoincide(ps.get(0))|| ps.get(3).isCoincide(ps.get(2))) { 17 ps1.add(ps.get(0));ps1.add(ps.get(1));ps1.add(ps.get(2)); 18 } 19 return ps1; 20 }
2.修改原本代码不对应的地方,如三角形类getsideline方法。
整体上,在父类Shapes类中getArea方法修改为通用的(运用点集),这样也可以减少代码量。

public double getArea(ArrayList ps){ return PolygonArea.area(ps) ; }
在后续找到一个分割多边形的通用方法,减少代码量。
虽然本次用的判断点与多边形位置关系是用面积的方法,但后续可以改为老师要求的射线法,挑战自己。
五、总结
对于这一阶段大部分还是在继承方面走,但是明显感觉到再向抽象与接口这边走了,虽然没有用到。对于继承的学习,可能就作业来说到此结束,但是通过这阶段的学习(三个星期)不能说长,也不能说短,要说把继承学好也不可能,但是总能了解基础的用法。对于ArrayList容器来说,从网课开始老师就讲了,所以到现在也能熟练掌握其用法。学习到了许多几何方法,对特殊情况的判断特殊处理。到了现在,也基本达到从面对过程到面向对象的蜕变。对于作业这方面虽然不算多,但是都挤在一起就会没有时间写。作业和实验上,老师可以继续将作业发布可以把题目提前一点,可以在星期五的下午发布PTA,还有作业或实验提交在哪里也可以先发布。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义