面对对象程序设计题目分析与心得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 }
View Code
复制代码

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 }
View Code
复制代码

 

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         }
View Code
复制代码

 

  (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 }
View Code
复制代码

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 }
View Code
复制代码

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;
    }
View Code
复制代码

  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;
    }
View Code
复制代码

  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     }
View Code
复制代码

  2.修改原本代码不对应的地方,如三角形类getsideline方法。

整体上,在父类Shapes类中getArea方法修改为通用的(运用点集),这样也可以减少代码量。

public double getArea(ArrayList ps){
    return PolygonArea.area(ps) ;
}
View Code

在后续找到一个分割多边形的通用方法,减少代码量。

虽然本次用的判断点与多边形位置关系是用面积的方法,但后续可以改为老师要求的射线法,挑战自己。

五、总结

  对于这一阶段大部分还是在继承方面走,但是明显感觉到再向抽象与接口这边走了,虽然没有用到。对于继承的学习,可能就作业来说到此结束,但是通过这阶段的学习(三个星期)不能说长,也不能说短,要说把继承学好也不可能,但是总能了解基础的用法。对于ArrayList容器来说,从网课开始老师就讲了,所以到现在也能熟练掌握其用法。学习到了许多几何方法,对特殊情况的判断特殊处理。到了现在,也基本达到从面对过程到面向对象的蜕变。对于作业这方面虽然不算多,但是都挤在一起就会没有时间写。作业和实验上,老师可以继续将作业发布可以把题目提前一点,可以在星期五的下午发布PTA,还有作业或实验提交在哪里也可以先发布。

posted @   沫河口岸  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示