PTA第四、五次大作业及期中考试总结分析——BLOG_2
前言:
第四次的大作业总的来说题目量不大,有了上一次作业三角形的铺垫,来写四边形的情况也就有了准备。这次作业就中间第二题与四边形有关的计算难度较大,花费的时间较多,另外两题都比较的简单。设计到的知识点有正则表达式的运用,四边形的相应判断条件学习,四边形类的设计以及银行业务类的设计。
第五次大作业是最难的一次大作业,它不仅新增了一个五边形的类,还需要运用到三角形与四边形的类,就是这次作业让我意识到之前写的两个类的可用性及其的差,没有什么复用性,在做第二题的时候就干脆重新设计了自己的类,以及增加了一个图形的父类,发现这样写大大简化了自己之前的代码。做这道题要学的知识很多,例如多边形面积计算,求两个图形重叠面积,判断两个图形位置关系等。
期中考试简单,需要注意的就是代码与题目所给类图对应。
PTA第四次大作业
(1)题目1
7-1 sdut-String-2 识蛟龙号载人深潜,立科技报国志(II)(正则表达式)
请编写程序,实现如下功能:读入关于蛟龙号载人潜水器探测数据的多行字符串,从给定的信息找出数字字符,输出每行的数字之和。提示 若输入为“2012年2月”,则该行的输出为:2014。若干个连续的数字字
符作为一个整体,以十进制形式相加。
输入格式:
读入关于蛟龙号载人潜水器探测数据的多行字符串,每行字符不超过80个字符。以"end"结束。
输出格式:
与输入行相对应的各个整数之和。
输入样例:
2012年6月27日11时47分,中国“蛟龙”再次刷新“中国深度”——下潜7062米 6月15日,6671米 6月19日,6965米 6月22日,6963米 6月24日,7020米 6月27日,7062米 下潜至7000米,标志着我国具备了载人到达全球99%以上海洋深处进行作业的能力 end
输出样例:
9165 6692 6990 6991 7050 7095 7099
-
设计与分析
这道题目比较的简单,没有什么好分析的。我就直接给出我的代码的圈复杂度分析图和我的类图。
-
踩坑心得
这道题主要就是提取出每行输入的数字,没有什么坑。
-
改进建议
这道题主要可能就是训练我们对正则表达式的使用,但是我一开始没注意,采用的是字符串提取比较的方法。其实用正则表达式更为的简单,也能减少代码的圈复杂度,可以简化代码。
采用正则表达式的方法的主要代码:

1 while(!s1.matches("end")) 2 { 3 String[] s=s1.split("\\D+"); 4 for(i=0;i<s.length;i++) 5 { 6 if(!(s[i].matches(""))) 7 { 8 a=s[i]; 9 b=Integer.parseInt(a); 10 sum=sum+b; 11 } 12 } 13 System.out.println(sum); 14 sum=0; 15 s1=input.nextLine(); 16 }
-
源码附录

1 import java.util.Scanner; 2 3 public class Main{ 4 public static void main(String[] args) { 5 Scanner in = new Scanner(System.in); 6 String s = in.nextLine(); 7 String s1 = ""; 8 int sum = 0; 9 int x = 0, j; 10 while (!s.equals("end")) { 11 sum = 0; 12 for (int i = 0; i < s.length(); i++) { 13 if (s.charAt(i) >= '0' && s.charAt(i) <= '9') { 14 s1 = ""; 15 for (j = i; j < s.length(); j++) { 16 17 if (s.charAt(j) >= '0' && s.charAt(j) <= '9') 18 s1 = s1 + s.charAt(j); 19 else 20 break; 21 } 22 23 x = Integer.valueOf(s1); 24 sum = sum + x; 25 i = j; 26 } 27 } 28 System.out.println(sum); 29 s = in.nextLine(); 30 } 31 } 32 }
(2)题目2
7-2 点线形系列4-凸四边形的计算
用户输入一组选项和数据,进行与四边形有关的计算。
1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。 2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral" 3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral" 4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成
两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a quadrilateral
or triangle"。后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s: 1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。 2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y 5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the
quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the quadrilateral"。若后四个点不符合四边形或三角形,
输出"not a quadrilateral or triangle"。
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。 异常情况输出: 如果不符合基本格式,输出"Wrong Format"。 如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。 注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为
1.0 选项1、2、3中,若四边形四个点中有重合点,输出"points coincide"。 选项4中,若前两个输入线的点重合,输出"points coincide"。
样例链接:
https://images.ptausercontent.com/a221d9c0-1339-4085-bd8d-ac9e0b1ecd36.pdf
-
设计与分析
圈复杂度:
类图:
注:点、线、三角形的类图之前博客做过分析,这里主要分析四边形的类图。
属性:四边形由四个点构成,也可以说是由四条边构成。我这里把它的四个点以及四条边都当成了四边形的属性来写。
情况1:要求判断输入的点能否构成三角形,所有需要一个返回值为布尔类型的方法去判断输入的点能否构成四角形。
采用的方法是相邻的边不共线,不相邻的边不相交的判断方法。

1 boolean is_sibian() { 2 if ((p4.y - p3.y) * (p4.x - p2.x) == (p4.y - p2.y) * (p4.x - p3.x)) 3 return false; 4 else if ((p4.y - p3.y) * (p4.x - p1.x) == (p4.y - p1.y) * (p4.x - p3.x)) 5 return false; 6 else if ((p4.y - p2.y) * (p4.x - p1.x) == (p4.y - p1.y) * (p4.x - p2.x)) 7 return false; 8 else if ((p3.y - p2.y) * (p3.x - p1.x) == (p3.y - p1.y) * (p3.x - p2.x)) 9 return false; 10 Point[] pt1 = new Point[1]; 11 pt1[0] = null; 12 line.jiaodian(b, d, pt1, 0); 13 if (pt1[0] != null) { 14 if (line.judgeinline(b, pt1[0]) && line.judgeinline(d, pt1[0])) 15 return false; 16 else { 17 Point[] pt2 = new Point[1]; 18 pt2[0] = null; 19 line.jiaodian(a, c, pt2, 0); 20 if (pt2[0] != null) 21 if (line.judgeinline(a, pt2[0]) && line.judgeinline(c, pt2[0])) 22 return false; 23 else 24 return true; 25 else 26 return true; 27 } 28 } 29 30 else { 31 Point[] pt2 = new Point[1]; 32 pt2[0] = null; 33 line.jiaodian(a, c, pt2, 0); 34 if (pt2[0] != null) 35 if (line.judgeinline(a, pt2[0])) 36 return false; 37 else 38 return true; 39 else 40 return true; 41 } 42 43 }
情况2:要求判断菱形、举行、正方形,所以需要一个方法去判断四边形的类型。
首先前提是判断是不是平行四边形,在此基础上,判断是不是正方形(四边相等,对角线相等),再判断是不是菱形(四边相等)最后判断是不是矩形(对角线相等)。

boolean pxsbx() { if (line.judgepinxing(a, c) && line.judgepinxing(d, b)) return true; else return false; } String l_j_z(sibian e) { String s; if (e.pxsbx()) { line l1 = new line(p3, p1); line l2 = new line(p2, p4); if ((a.length == b.length && c.length == d.length && c.length == b.length) && Math.abs(l1.length - l2.length) < 0.000001) { s = "zfx"; } else { if (a.length == b.length && c.length == d.length && c.length == b.length) s = "lx"; else if (Math.abs(l1.length - l2.length) < 0.000001) s = "jx"; else s = "ptsbx"; } } else s = "ptsbx"; return s; }
情况3:判断凸凹四角形,并且计算面积和周长。
判断凸凹四边形采用的是:向量叉乘原理。求面积采用的还是分割成三角形来求解。
学习向量叉乘链接:
http://t.csdn.cn/48o0Q

1 String tuorao() { 2 String s = ""; 3 double z1, z2, z3, z4; 4 z1 = ((p2.x - p1.x) * (p4.y - p1.y) - (p4.x - p1.x) * (p2.y - p1.y)); 5 z2 = ((p4.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p4.y - p1.y)); 6 z3 = ((p4.x - p2.x) * (p3.y - p2.y) - (p3.x - p2.x) * (p4.y - p2.y)); 7 z4 = ((p3.x - p2.x) * (p1.y - p2.y) - (p1.x - p2.x) * (p3.y - p2.y)); 8 if (z1 * z2 * z3 * z4 > 0) 9 s = "true"; 10 else 11 s = "false"; 12 13 return s; 14 } 15 16 17 double zhouchang() { 18 return a.length + b.length + c.length + d.length; 19 } 20 21 22 23 double area() { 24 Point[] pt1 = new Point[3]; 25 pt1[0] = p1; 26 pt1[1] = p2; 27 pt1[2] = p3; 28 29 Point[] pt2 = new Point[3]; 30 pt2[0] = p1; 31 pt2[1] = p2; 32 pt2[2] = p4; 33 34 Point[] pt3 = new Point[3]; 35 pt3[0] = p1; 36 pt3[1] = p4; 37 pt3[2] = p3; 38 39 Point[] pt4 = new Point[3]; 40 pt4[0] = p3; 41 pt4[1] = p2; 42 pt4[2] = p4; 43 44 triangle s1 = new triangle(pt3); 45 triangle s2 = new triangle(pt1); 46 triangle s3 = new triangle(pt2); 47 triangle s4 = new triangle(pt4); 48 49 double area1 = s1.area() + s2.area(); 50 double area2 = s3.area() + s4.area(); 51 if (area1 >= area2) 52 return area2; 53 else 54 return area1; 55 56 }
情况4:判断线与三角形/四边形交点个数以及当有两个交点时,按照分割图形面积大小由小到大输出面积。
首先需要判断四个点是如何能够形成三角形的,总的来说有两种情况:有一个点与另外一个点重合;中间点在边线上,例如:p1,p2,p3,p4;其中p2是p1、p3的中间点,p4是p3、p2的中间点。我们要去除重复点以及中间点去判断剩下的点能不能构成三角形。再用上一次大作业的三角形与线的交点部分的代码。
对于四边形而言,线与四边形的交点情况有以下几种:
1个交点和0个交点(1个交点的情况其实是有两个交点,但是是重复点)
2个交点的情况(交点个数可能为2、3、4,有重复点)。这里计算面积的时一定要注意重复点的处理以及分割后的两个图形的点的组成情况,要分类处理,还有就是注意分割后的图形。

1 //判断四个点成三角形 2 int sanjiaoxing() { 3 int flag = 0; 4 if (Point.judgeeq(p1, p2) || Point.judgeeq(p1, p3) || Point.judgeeq(p1, p4) || Point.judgeeq(p2, p3) 5 || Point.judgeeq(p2, p4) || Point.judgeeq(p3, p4)) { 6 Point[] pt1 = new Point[3]; 7 if (Point.judgeeq(p1, p2)) { 8 pt1[0] = p1; 9 pt1[1] = p3; 10 pt1[2] = p4; 11 flag = 1; 12 } else if (Point.judgeeq(p1, p3)) { 13 pt1[0] = p1; 14 pt1[1] = p2; 15 pt1[2] = p4; 16 flag = 2; 17 } else if (Point.judgeeq(p1, p4)) { 18 pt1[0] = p1; 19 pt1[1] = p3; 20 pt1[2] = p2; 21 flag = 3; 22 } else if (Point.judgeeq(p3, p2)) { 23 pt1[0] = p1; 24 pt1[1] = p3; 25 pt1[2] = p4; 26 flag = 4; 27 } else if (Point.judgeeq(p4, p2)) { 28 pt1[0] = p1; 29 pt1[1] = p3; 30 pt1[2] = p4; 31 flag = 5; 32 } else if (Point.judgeeq(p4, p3)) { 33 pt1[0] = p1; 34 pt1[1] = p2; 35 pt1[2] = p4; 36 flag = 6; 37 } 38 triangle sTriangle = new triangle(pt1); 39 if (!sTriangle.can_triangle()) 40 flag = 0; 41 42 } else { 43 Point[] pt1 = new Point[3]; 44 pt1[0] = p1; 45 pt1[1] = p2; 46 pt1[2] = p3; 47 line l1 = new line(p1, p3); 48 49 Point[] pt2 = new Point[3]; 50 pt2[0] = p1; 51 pt2[1] = p2; 52 pt2[2] = p4; 53 line l2 = new line(p2, p4); 54 55 Point[] pt3 = new Point[3]; 56 pt3[0] = p1; 57 pt3[1] = p4; 58 pt3[2] = p3; 59 line l3 = new line(p3, p1); 60 61 Point[] pt4 = new Point[3]; 62 pt4[0] = p2; 63 pt4[1] = p4; 64 pt4[2] = p3; 65 line l4 = new line(p4, p2); 66 67 if (line.judgegonxian(pt1) && !l1.judgein_line(p4) && line.judgeinline(l1, p2)) { 68 flag = 7; 69 70 } else if (line.judgegonxian(pt2) && !l2.judgein_line(p3) && line.judgeinline(l2, p1)) { 71 flag = 8; 72 73 } else if (line.judgegonxian(pt3) && !l3.judgein_line(p2) && line.judgeinline(l3, p4)) { 74 flag = 9; 75 76 } else if (line.judgegonxian(pt4) && !l4.judgein_line(p1) && line.judgeinline(l4, p3)) { 77 flag = 10; 78 79 } else { 80 flag = 0; 81 } 82 } 83 return flag; 84 } 85 86 } 87 88 89 90 //求四边形与线的交点情况主要代码 91 else if (sb1.is_sibian()) { 92 if (line.judgechonghe(l, sb1.a) || line.judgechonghe(l, sb1.b) || line.judgechonghe(l, sb1.c) 93 || line.judgechonghe(l, sb1.d)) 94 System.out.println("The line is coincide with one of the lines"); 95 else { 96 97 int count = 0; 98 Point[] jd = new Point[4]; 99 line[] jx = new line[4]; 100 if (line.jiaodian(sb1.a, l, jd, count)) { 101 102 jx[count] = sb1.a; 103 count++; 104 105 } 106 if (line.jiaodian(sb1.b, l, jd, count)) { 107 108 jx[count] = sb1.b; 109 count++; 110 } 111 if (line.jiaodian(sb1.c, l, jd, count)) { 112 113 jx[count] = sb1.c; 114 count++; 115 } 116 if (line.jiaodian(sb1.d, l, jd, count)) { 117 118 jx[count] = sb1.d; 119 count++; 120 } 121 double area1, area2; 122 if (count < 2) 123 System.out.println(count); 124 else if (count == 2) { 125 if (jd[0].x == jd[1].x && jd[0].y == jd[1].y) 126 System.out.println(count - 1); 127 else { 128 line.jiaodian(jx[0], jx[1], jd, 2); 129 130 if (jd[2] == null) { 131 Point[] pp1 = new Point[4]; 132 if (jx[0] == sb1.a && jx[1] == sb1.c) { 133 pp1[0] = jd[0]; 134 pp1[1] = p[3]; 135 pp1[2] = p[4]; 136 pp1[3] = jd[1]; 137 } else { 138 pp1[0] = p[2]; 139 pp1[1] = p[3]; 140 pp1[2] = jd[0]; 141 pp1[3] = jd[1]; 142 } 143 sibian sb2 = new sibian(pp1); 144 area1 = sb2.area(); 145 area2 = sb1.area() - sb2.area(); 146 double max, min; 147 if (area1 > area2) { 148 max = area1; 149 min = area2; 150 151 } else { 152 max = area2; 153 min = area1; 154 } 155 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 156 157 } else { 158 triangle tri = new triangle(jd); 159 area1 = tri.area(); 160 area2 = sb1.area() - tri.area(); 161 double max, min; 162 if (area1 > area2) { 163 max = area1; 164 min = area2; 165 166 } else { 167 max = area2; 168 min = area1; 169 } 170 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 171 } 172 } 173 174 } else { 175 Point[] pp = new Point[3]; 176 if (jd[0].x == sb1.p2.x && jd[0].y == sb1.p2.y) { 177 pp[0] = sb1.p1; 178 pp[1] = sb1.p2; 179 pp[2] = sb1.p4; 180 } else { 181 pp[0] = sb1.p1; 182 pp[1] = sb1.p2; 183 pp[2] = sb1.p3; 184 } 185 triangle tri = new triangle(pp); 186 area1 = tri.area(); 187 area2 = sb1.area() - tri.area(); 188 double max, min; 189 if (area1 > area2) { 190 max = area1; 191 min = area2; 192 193 } else { 194 max = area2; 195 min = area1; 196 } 197 System.out.println("2" + " " + df.format(min) + " " + df.format(max)); 198 } 199 200 } 201 202 }
情况5:判断点在图形的位置(内部、外部、线上)
采用面积法:由下图可知,在内部时,点与四边形的交点组成的四个三角形的面积和等于四边形的面积,在外部其面积和大于四边形面积。当面积等于四边形面积时,先判断是不是在边线上。
-
踩坑心得
第一坑:在求四边形面积的时候,直接将它分割成两个三角形,再求三角形面积之和,这种方法对于凸四边形来说是正确的,但是对于凹四边形来说,就会出现错误。如下图所示,当分成的三角形是p1、p2、p3以及p1、p2、p4时,很明显的俩个三角形的面积要大于原本四边形的面积。
第二坑:在情况4求交点算面积的情况中,一开始忽略了一条线可以把四边形分成两个四边形的情况导致有部分情况测试点过不去。
第三坑:精度问题!!!在判断点在图形外时,没有使用面积和>0.000000001,导致情况5有一个测试点一直都过不去。
第四坑:这里也是这道题目的难点!!!要理解题目中给到的判断三角形的条件有两种。第一种很好理解,就是有一个重复点,第二个条件比较难理解,就是不是三点共线且另外一个点不在线上就是能成三角形的条件,因为需要考虑连线的顺序,所以必须要是中间点,其次,要记住p5、p1是连这的,所以p5是p4、p1的中间点,p1、是p5、p2的中间点。
-
改进建议
这道题目从圈复杂度分析图来看,代码的圈复杂度很高,说明代码的可读性和可靠性很低。代码的总行数有1000左右,说明代码可以简化的地方有很多,一开始从三角形开始,就可以考虑使用数组来存点和线,在利用循环来遍历。还有就是很多的重复功能没有集中写一个方法,比如去掉重复点,去掉中间点,判断交点在端点上还是线上线外,集中将这些要求完成的内容各写一个方法之后去调用这个方法可以简化代码。
-
源码附录

1 import java.text.DecimalFormat; 2 import java.util.Scanner; 3 4 public class MOOC_text { 5 public static void main(String[] args) { 6 Scanner in = new Scanner(System.in); 7 String str1 = in.nextLine(); 8 char ch1 = str1.charAt(0); 9 char ch2 = str1.charAt(1); 10 String str = str1.substring(2); 11 if (ch2 != ':') { 12 System.out.println("Wrong Format"); 13 return; 14 } 15 switch (ch1) { 16 case '1': { 17 int n = 4; 18 Point[] p = new Point[n]; 19 int shuling = Point.getp(str, p, n); 20 if (shuling == 1) { 21 22 if (!Point.judgeeq(p[0], p[1]) && !Point.judgeeq(p[0], p[2]) && !Point.judgeeq(p[0], p[3]) 23 && !Point.judgeeq(p[1], p[2]) && !Point.judgeeq(p[1], p[3]) && !Point.judgeeq(p[2], p[3])) { 24 sibian sb1 = new sibian(p); 25 if (sb1.is_sibian()) { 26 if (sb1.pxsbx()) 27 System.out.println("true true"); 28 else { 29 System.out.println("true false"); 30 } 31 32 } else 33 System.out.println("false false"); 34 } else 35 System.out.println("points coincide"); 36 37 } else if (shuling != 1 && shuling != -1) { 38 System.out.println("wrong number of points"); 39 } 40 break; 41 } 42 case '2': { 43 int n = 4; 44 Point[] p = new Point[n]; 45 int shuling = Point.getp(str, p, n); 46 if (shuling == 1) { 47 if (!Point.judgeeq(p[0], p[1]) && !Point.judgeeq(p[0], p[2]) && !Point.judgeeq(p[0], p[3]) 48 && !Point.judgeeq(p[1], p[2]) && !Point.judgeeq(p[1], p[3]) && !Point.judgeeq(p[2], p[3])) { 49 sibian sb1 = new sibian(p); 50 if (sb1.is_sibian()) { 51 if (sb1.l_j_z(sb1).equals("zfx")) 52 System.out.println("true true true"); 53 else if (sb1.l_j_z(sb1).equals("jx")) { 54 System.out.println("false true false"); 55 56 } else if (sb1.l_j_z(sb1).equals("lx")) 57 System.out.println("true false false"); 58 else { 59 System.out.println("false false false"); 60 } 61 62 } else 63 System.out.println("not a quadrilateral"); 64 } else 65 System.out.println("not a quadrilateral"); 66 67 } else if (shuling != 1 && shuling != -1) { 68 System.out.println("wrong number of points"); 69 } 70 break; 71 } 72 case '3': { 73 int n = 4; 74 Point[] p = new Point[n]; 75 int shuling = Point.getp(str, p, n); 76 if (shuling == 1) { 77 78 if (!Point.judgeeq(p[0], p[1]) && !Point.judgeeq(p[0], p[2]) && !Point.judgeeq(p[0], p[3]) 79 && !Point.judgeeq(p[1], p[2]) && !Point.judgeeq(p[1], p[3]) && !Point.judgeeq(p[2], p[3])) { 80 sibian sb1 = new sibian(p); 81 DecimalFormat df = new DecimalFormat("0.0##"); 82 if (sb1.is_sibian()) { 83 if (sb1.tuorao().equals("true")) { 84 System.out.print("true "); 85 System.out.println(df.format(sb1.zhouchang()) + " " + df.format(sb1.area())); 86 } else { 87 System.out.print("false "); 88 System.out.println(df.format(sb1.zhouchang()) + " " + df.format(sb1.area())); 89 } 90 } else 91 System.out.println("not a quadrilateral"); 92 } else 93 System.out.println("points coincide"); 94 95 } else if (shuling != 1 && shuling != -1) { 96 System.out.println("wrong number of points"); 97 } 98 break; 99 } 100 case '4': { 101 int n = 6; 102 Point[] p = new Point[n]; 103 int shuling = Point.getp(str, p, n); 104 DecimalFormat df = new DecimalFormat("0.0##"); 105 if (shuling == 1) { 106 line l = new line(p[0], p[1]); 107 if (Point.judgeeq(p[0], p[1])) 108 System.out.println("points coincide"); 109 else { 110 Point[] pt2 = new Point[4]; 111 pt2[0] = p[2]; 112 pt2[1] = p[3]; 113 pt2[2] = p[4]; 114 pt2[3] = p[5]; 115 sibian sb1 = new sibian(pt2); 116 int flag = 0; 117 flag = sb1.sanjiaoxing(); 118 // System.out.println(flag); 119 if (flag != 0) { 120 Point[] pt1 = new Point[3]; 121 if (flag == 1 || flag == 4 || flag == 7) { 122 pt1[0] = p[2]; 123 pt1[1] = p[4]; 124 pt1[2] = p[5]; 125 126 } else if (flag == 2 || flag == 10) { 127 pt1[0] = p[2]; 128 pt1[1] = p[3]; 129 pt1[2] = p[5]; 130 131 } else if (flag == 3 || flag == 5 || flag == 6 || flag == 9) { 132 pt1[0] = p[2]; 133 pt1[1] = p[3]; 134 pt1[2] = p[4]; 135 136 } else if (flag == 8) { 137 pt1[0] = p[3]; 138 pt1[1] = p[4]; 139 pt1[2] = p[5]; 140 141 } 142 triangle sanTriangle = new triangle(pt1); 143 if (line.judgechonghe(l, sanTriangle.a) || line.judgechonghe(l, sanTriangle.b) 144 || line.judgechonghe(l, sanTriangle.c)) { 145 System.out.println("The line is coincide with one of the lines"); 146 } else { 147 int count = 0; 148 Point[] jd = new Point[3]; 149 line[] jx = new line[3]; 150 if (line.jiaodian(sanTriangle.a, l, jd, count)) { 151 152 jx[count] = sanTriangle.a; 153 count++; 154 155 } 156 if (line.jiaodian(sanTriangle.b, l, jd, count)) { 157 158 jx[count] = sanTriangle.b; 159 count++; 160 } 161 if (line.jiaodian(sanTriangle.c, l, jd, count)) { 162 163 jx[count] = sanTriangle.c; 164 count++; 165 } 166 167 if (count < 2) 168 System.out.println(count); 169 else if (count == 2) { 170 double area1, area2; 171 if (jd[1].x == jd[0].x && jd[0].y == jd[1].y) 172 System.out.println(count - 1); 173 else { 174 line.jiaodian(jx[0], jx[1], jd, 2); 175 triangle tri = new triangle(jd); 176 area1 = tri.area(); 177 area2 = sanTriangle.area() - tri.area(); 178 double max, min; 179 if (area1 > area2) { 180 max = area1; 181 min = area2; 182 183 } else { 184 max = area2; 185 min = area1; 186 } 187 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 188 } 189 190 } else { 191 double area1, area2; 192 if (jd[0].x == jd[1].x && jd[0].y == jd[1].y) { 193 jd[1].x = jd[2].x; 194 jd[1].y = jd[2].y; 195 line.jiaodian(jx[0], jx[2], jd, 2); 196 } 197 198 if (jd[0].x == jd[2].x && jd[0].y == jd[2].y) { 199 line.jiaodian(jx[0], jx[1], jd, 2); 200 } 201 202 if (jd[2].x == jd[1].x && jd[2].y == jd[1].y) { 203 line.jiaodian(jx[0], jx[2], jd, 2); 204 } 205 206 triangle tri = new triangle(jd); 207 area1 = tri.area(); 208 area2 = sanTriangle.area() - tri.area(); 209 double max, min; 210 if (area1 > area2) { 211 max = area1; 212 min = area2; 213 214 } else { 215 max = area2; 216 min = area1; 217 } 218 count--; 219 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 220 } 221 222 } 223 224 } else if (sb1.is_sibian()) { 225 if (line.judgechonghe(l, sb1.a) || line.judgechonghe(l, sb1.b) || line.judgechonghe(l, sb1.c) 226 || line.judgechonghe(l, sb1.d)) 227 System.out.println("The line is coincide with one of the lines"); 228 else { 229 230 int count = 0; 231 Point[] jd = new Point[4]; 232 line[] jx = new line[4]; 233 if (line.jiaodian(sb1.a, l, jd, count)) { 234 235 jx[count] = sb1.a; 236 count++; 237 238 } 239 if (line.jiaodian(sb1.b, l, jd, count)) { 240 241 jx[count] = sb1.b; 242 count++; 243 } 244 if (line.jiaodian(sb1.c, l, jd, count)) { 245 246 jx[count] = sb1.c; 247 count++; 248 } 249 if (line.jiaodian(sb1.d, l, jd, count)) { 250 251 jx[count] = sb1.d; 252 count++; 253 } 254 double area1, area2; 255 if (count < 2) 256 System.out.println(count); 257 else if (count == 2) { 258 if (jd[0].x == jd[1].x && jd[0].y == jd[1].y) 259 System.out.println(count - 1); 260 else { 261 line.jiaodian(jx[0], jx[1], jd, 2); 262 263 if (jd[2] == null) { 264 Point[] pp1 = new Point[4]; 265 if (jx[0] == sb1.a && jx[1] == sb1.c) { 266 pp1[0] = jd[0]; 267 pp1[1] = p[3]; 268 pp1[2] = p[4]; 269 pp1[3] = jd[1]; 270 } else { 271 pp1[0] = p[2]; 272 pp1[1] = p[3]; 273 pp1[2] = jd[0]; 274 pp1[3] = jd[1]; 275 } 276 sibian sb2 = new sibian(pp1); 277 area1 = sb2.area(); 278 area2 = sb1.area() - sb2.area(); 279 double max, min; 280 if (area1 > area2) { 281 max = area1; 282 min = area2; 283 284 } else { 285 max = area2; 286 min = area1; 287 } 288 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 289 290 } else { 291 triangle tri = new triangle(jd); 292 area1 = tri.area(); 293 area2 = sb1.area() - tri.area(); 294 double max, min; 295 if (area1 > area2) { 296 max = area1; 297 min = area2; 298 299 } else { 300 max = area2; 301 min = area1; 302 } 303 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 304 } 305 } 306 307 } else { 308 Point[] pp = new Point[3]; 309 if (jd[0].x == sb1.p2.x && jd[0].y == sb1.p2.y) { 310 pp[0] = sb1.p1; 311 pp[1] = sb1.p2; 312 pp[2] = sb1.p4; 313 } else { 314 pp[0] = sb1.p1; 315 pp[1] = sb1.p2; 316 pp[2] = sb1.p3; 317 } 318 triangle tri = new triangle(pp); 319 area1 = tri.area(); 320 area2 = sb1.area() - tri.area(); 321 double max, min; 322 if (area1 > area2) { 323 max = area1; 324 min = area2; 325 326 } else { 327 max = area2; 328 min = area1; 329 } 330 System.out.println("2" + " " + df.format(min) + " " + df.format(max)); 331 } 332 333 } 334 335 } else 336 System.out.println("not a quadrilateral or triangle"); 337 338 } 339 } else if (shuling != -1) { 340 System.out.println("wrong number of points"); 341 } 342 break; 343 } 344 case '5': { 345 int n = 5; 346 Point[] p = new Point[n]; 347 int shuling = Point.getp(str, p, n); 348 if (shuling == 1) { 349 Point[] pt2 = new Point[4]; 350 pt2[0] = p[1]; 351 pt2[1] = p[2]; 352 pt2[2] = p[3]; 353 pt2[3] = p[4]; 354 355 sibian sb1 = new sibian(pt2); 356 int flag = 0; 357 flag = sb1.sanjiaoxing(); 358 if (flag != 0) { 359 360 Point[] pt1 = new Point[3]; 361 if (flag == 1 || flag == 4 || flag == 7) { 362 pt1[0] = p[1]; 363 pt1[1] = p[3]; 364 pt1[2] = p[4]; 365 366 } else if (flag == 2 || flag == 10) { 367 pt1[0] = p[1]; 368 pt1[1] = p[2]; 369 pt1[2] = p[4]; 370 371 } else if (flag == 3 || flag == 5 || flag == 6 || flag == 9) { 372 pt1[0] = p[1]; 373 pt1[1] = p[2]; 374 pt1[2] = p[3]; 375 376 } else if (flag == 8) { 377 pt1[0] = p[2]; 378 pt1[1] = p[3]; 379 pt1[2] = p[4]; 380 381 } 382 triangle sanTriangle = new triangle(pt1); 383 if (sanTriangle.can_triangle()) { 384 Point[] s1 = new Point[3]; 385 Point[] s2 = new Point[3]; 386 Point[] s3 = new Point[3]; 387 s1[0] = p[0]; 388 s1[1] = pt1[0]; 389 s1[2] = pt1[1]; 390 s2[0] = p[0]; 391 s2[1] = pt1[0]; 392 s2[2] = pt1[2]; 393 s3[0] = p[0]; 394 s3[1] = pt1[2]; 395 s3[2] = pt1[1]; 396 triangle t1 = new triangle(s1); 397 triangle t2 = new triangle(s2); 398 triangle t3 = new triangle(s3); 399 double area1, area2, area3, area4; 400 area1 = t1.area(); 401 area2 = t2.area(); 402 area3 = t3.area(); 403 area4 = sanTriangle.area(); 404 if (area1 + area2 + area3 - area4 > 0.000000001) 405 System.out.println("outof the triangle"); 406 else if (Math.abs(area1 + area2 + area3 - area4) < 0.0001) { 407 if (sanTriangle.a.judgein_line(p[0]) || sanTriangle.b.judgein_line(p[0]) 408 || sanTriangle.c.judgein_line(p[0])) 409 System.out.println("on the triangle"); 410 else 411 System.out.println("in the triangle"); 412 } 413 414 } 415 416 } else if (sb1.is_sibian()) { 417 418 // else { 419 Point[] pp1 = new Point[3]; 420 pp1[0] = p[0]; 421 pp1[1] = p[1]; 422 pp1[2] = p[2]; 423 Point[] pp2 = new Point[3]; 424 pp2[0] = p[0]; 425 pp2[1] = p[2]; 426 pp2[2] = p[3]; 427 Point[] pp3 = new Point[3]; 428 pp3[0] = p[0]; 429 pp3[1] = p[3]; 430 pp3[2] = p[4]; 431 Point[] pp4 = new Point[3]; 432 pp4[0] = p[0]; 433 pp4[1] = p[1]; 434 pp4[2] = p[4]; 435 436 triangle s1 = new triangle(pp1); 437 triangle s2 = new triangle(pp2); 438 triangle s3 = new triangle(pp3); 439 triangle s4 = new triangle(pp4); 440 double x = s1.area() + s2.area() + s3.area() + s4.area(); 441 if (x - sb1.area() > 0.00001) 442 System.out.println("outof the quadrilateral"); 443 else if (Math.abs(x - sb1.area()) < 0.0001) 444 if ((line.judgeinline(sb1.a, p[0]) && sb1.a.judgein_line(p[0])) 445 || (line.judgeinline(sb1.b, p[0]) && sb1.b.judgein_line(p[0])) 446 || (line.judgeinline(sb1.c, p[0]) && sb1.c.judgein_line(p[0])) 447 || (line.judgeinline(sb1.d, p[0]) && sb1.d.judgein_line(p[0]))) 448 System.out.println("on the quadrilateral"); 449 else 450 System.out.println("in the quadrilateral"); 451 // } 452 453 } else 454 System.out.println("not a quadrilateral or triangle"); 455 456 } else if (shuling != 1 && shuling != -1) { 457 System.out.println("wrong number of points"); 458 } 459 break; 460 } 461 default: 462 System.out.println("Wrong Format"); 463 break; 464 } 465 466 } 467 } 468 469 class Point { 470 double x, y; 471 472 Point(String x1, String y1) { 473 x = Double.valueOf(x1); 474 y = Double.valueOf(y1); 475 } 476 477 double getdistan(Point p) { 478 double t = Math.sqrt(Math.pow(x - p.x, 2) + Math.pow(y - p.y, 2)); 479 return t; 480 } 481 482 static Boolean judge(String str) { 483 if (!str.matches("^[+-]?(0|(0\\.[\\d]+)?|[1-9][0-9]*(\\.[\\d]+)?)$")) { 484 return false; 485 } else 486 return true; 487 488 } 489 490 static int getp(String str, Point[] p, int sizE) 491 492 { 493 int count = 0; 494 int m = 0; 495 String[] A = str.split(" "); 496 for (String B : A) { 497 int i = 0; 498 String[] C = B.split(","); 499 if (C.length != 2) { 500 System.out.println("Wrong Format"); 501 return -1; 502 } 503 String[] num = B.split(","); 504 for (String D : C) { 505 506 if (!Point.judge(C[i])) { 507 System.out.println("Wrong Format"); 508 return -1; 509 } 510 num[i] = D; 511 i++; 512 } 513 if (m < sizE && i == 2) { 514 p[m] = new Point(num[0], num[1]); 515 m++; 516 } 517 518 count++; 519 } 520 if (count == sizE) 521 return 1; 522 else 523 return count; 524 525 } 526 527 static boolean judgeeq(Point p1, Point p2) { 528 if (p1.x == p2.x && p1.y == p2.y) 529 return true; 530 else 531 return false; 532 } 533 534 } 535 536 class line { 537 Point p1; 538 Point p2; 539 double k; 540 double length; 541 542 line(Point a, Point b) { 543 p1 = a; 544 p2 = b; 545 if (p1.x != p2.x) 546 k = (p2.y - p1.y) / (p2.x - p1.x); 547 length = a.getdistan(b); 548 } 549 550 boolean xielv() { 551 552 if (p1.x == p2.x) 553 return false; 554 else 555 return true; 556 } 557 558 double distance(Point a) { 559 560 double l = (Math.abs((p1.y - p2.y) * a.x + (p2.x - p1.x) * a.y + p1.x * p2.y)) 561 / (Math.sqrt(Math.pow(p1.y - p2.y, 2) + Math.pow(p1.x - p2.x, 2))); 562 return l; 563 } 564 565 static boolean judgepinxing(line a, line b) { 566 if (!a.xielv() && !b.xielv()) 567 return true; 568 else if (a.xielv() && b.xielv()) { 569 if (a.k == b.k) 570 return true; 571 else 572 return false; 573 } else 574 return false; 575 576 } 577 578 static boolean judgegonxian(Point[] p) { 579 String s; 580 if (!Point.judgeeq(p[0], p[1]) && !Point.judgeeq(p[2], p[1]) && !Point.judgeeq(p[0], p[2])) { 581 line p1 = new line(p[0], p[1]); 582 line p2 = new line(p[1], p[2]); 583 584 if (p1.xielv() && p2.xielv()) { 585 if (p1.k == p2.k) 586 return true; 587 else 588 return false; 589 } else if (p[0].x == p[1].x && p[1].x == p[2].x) 590 return true; 591 else { 592 return false; 593 } 594 } else 595 596 return true; 597 598 } 599 600 static boolean judgeinline(line a, Point p) { 601 double max1, min1; 602 if (a.p1.x > a.p2.x) { 603 max1 = a.p1.x; 604 min1 = a.p2.x; 605 } else { 606 max1 = a.p2.x; 607 min1 = a.p1.x; 608 } 609 610 double max2, min2; 611 if (a.p1.y > a.p2.y) { 612 max2 = a.p1.y; 613 min2 = a.p2.y; 614 } else { 615 max2 = a.p2.y; 616 min2 = a.p1.y; 617 } 618 if ((p.x < max1 && p.x > min1) || Math.abs(p.x - max1) < 0.000001 || Math.abs(p.x - min1) < 0.000001) { 619 if ((p.y < max2 && p.y > min2) || Math.abs(p.y - max2) < 0.000001 || Math.abs(p.y - min2) < 0.000001) 620 return true; 621 else 622 return false; 623 } else 624 return false; 625 } 626 627 static boolean jiaodian(line a, line b, Point[] jd, int count) { 628 double x = 0, y = 0, A1, B1, C1, A2, B2, C2; 629 if (line.judgepinxing(a, b)) 630 return false; 631 if (a.xielv() && b.xielv()) { 632 633 A1 = a.p1.y - a.p2.y; 634 B1 = a.p2.x - a.p1.x; 635 C1 = (a.p2.y - a.p1.y) * a.p1.x - (a.p2.x - a.p1.x) * a.p1.y; 636 A2 = b.p1.y - b.p2.y; 637 B2 = b.p2.x - b.p1.x; 638 C2 = (b.p2.y - b.p1.y) * b.p1.x - (b.p2.x - b.p1.x) * b.p1.y; 639 x = (B1 * C2 - B2 * C1) / (A1 * B2 - A2 * B1); 640 y = (A1 * C2 - A2 * C1) / (B1 * A2 - B2 * A1); 641 642 } else if (a.xielv() && !b.xielv()) { 643 x = b.p1.x; 644 y = a.p1.y + ((b.p1.x - a.p1.x) * (a.p2.y - a.p1.y) / (a.p2.x - a.p1.x)); 645 646 } else if (!a.xielv() && b.xielv()) { 647 x = a.p1.x; 648 y = b.p1.y + ((a.p1.x - b.p1.x) * (b.p2.y - b.p1.y) / (b.p2.x - b.p1.x)); 649 650 } 651 String x1 = "".valueOf(x); 652 String y1 = "".valueOf(y); 653 jd[count] = new Point(x1, y1); 654 if (line.judgeinline(a, jd[count])) 655 return true; 656 else 657 return false; 658 659 } 660 661 static boolean judgechonghe(line a, line b) { 662 if (line.judgepinxing(a, b) && a.judgein_line(b.p1)) 663 return true; 664 else 665 return false; 666 667 } 668 669 boolean judgein_line(Point p) { 670 double A, B, C; 671 A = p1.y - p2.y; 672 B = p2.x - p1.x; 673 C = (p2.y - p1.y) * p1.x - (p2.x - p1.x) * p1.y; 674 if ((A * p.x + B * p.y + C) == 0) 675 return true; 676 else { 677 return false; 678 } 679 } 680 681 } 682 683 class triangle { 684 Point p1, p2, p3; 685 line a, b, c; 686 687 triangle(Point[] p) { 688 p1 = p[0]; 689 p2 = p[1]; 690 p3 = p[2]; 691 a = new line(p[0], p[1]); 692 b = new line(p[0], p[2]); 693 c = new line(p[1], p[2]); 694 } 695 696 double zhouchang() { 697 double zc = a.length + b.length + c.length; 698 return zc; 699 700 } 701 702 double area() { 703 double area; 704 double p = (a.length + b.length + c.length) / 2.0; 705 area = Math.sqrt(p * (p - a.length) * (p - b.length) * (p - c.length)); 706 return area; 707 } 708 709 Point zhongxin() { 710 711 Point center; 712 double x1 = (p1.x + p2.x + p3.x) / 3.0; 713 double y1 = (p1.y + p2.y + p3.y) / 3.0; 714 String s1 = "".valueOf(x1); 715 String s2 = "".valueOf(y1); 716 center = new Point(s1, s2); 717 return center; 718 } 719 720 String bian_yao() { 721 String s1; 722 if (a.length == b.length && b.length == c.length) 723 s1 = "regular"; 724 else if (a.length == b.length || a.length == c.length || c.length == b.length) 725 s1 = "isosceles"; 726 else 727 s1 = "all not"; 728 return s1; 729 } 730 731 String z_r_d() { 732 double max = 0; 733 double x = 0; 734 if (a.length >= b.length && a.length >= c.length) { 735 max = a.length; 736 x = (b.length * b.length + c.length * c.length - max * max) / (2.0 * b.length * c.length); 737 } else if (b.length >= a.length && b.length >= c.length) { 738 max = b.length; 739 x = (a.length * a.length + c.length * c.length - max * max) / (2.0 * a.length * c.length); 740 } else if (c.length >= b.length && c.length >= a.length) { 741 max = c.length; 742 x = (b.length * b.length + a.length * a.length - max * max) / (2.0 * b.length * a.length); 743 } 744 double du; 745 String s = ""; 746 du = Math.acos(x); 747 du = (180.0 * du) / Math.PI; 748 if (du > 90 && du < 180) 749 s = "obtuse"; 750 else if (du > 0 && du < 90) 751 s = "acute"; 752 else if (du == 90) 753 s = "rightangled"; 754 return s; 755 } 756 757 boolean can_triangle() { 758 if (!Point.judgeeq(p1, p2) && !Point.judgeeq(p3, p2) && !Point.judgeeq(p1, p3)) { 759 Point[] p = new Point[3]; 760 p[0] = p1; 761 p[1] = p2; 762 p[2] = p3; 763 if (!line.judgegonxian(p)) 764 return true; 765 else 766 return false; 767 } else { 768 return false; 769 } 770 } 771 } 772 773 class sibian { 774 Point p1; 775 Point p2; 776 Point p3; 777 Point p4; 778 line a, b, c, d; 779 780 sibian(Point[] p) { 781 p1 = p[0]; 782 p2 = p[1]; 783 p3 = p[2]; 784 p4 = p[3]; 785 a = new line(p1, p2); 786 b = new line(p2, p3); 787 c = new line(p3, p4); 788 d = new line(p4, p1); 789 } 790 791 boolean is_sibian() { 792 if ((p4.y - p3.y) * (p4.x - p2.x) == (p4.y - p2.y) * (p4.x - p3.x)) 793 return false; 794 else if ((p4.y - p3.y) * (p4.x - p1.x) == (p4.y - p1.y) * (p4.x - p3.x)) 795 return false; 796 else if ((p4.y - p2.y) * (p4.x - p1.x) == (p4.y - p1.y) * (p4.x - p2.x)) 797 return false; 798 else if ((p3.y - p2.y) * (p3.x - p1.x) == (p3.y - p1.y) * (p3.x - p2.x)) 799 return false; 800 Point[] pt1 = new Point[1]; 801 pt1[0] = null; 802 line.jiaodian(b, d, pt1, 0); 803 if (pt1[0] != null) { 804 if (line.judgeinline(b, pt1[0]) && line.judgeinline(d, pt1[0])) 805 return false; 806 else { 807 Point[] pt2 = new Point[1]; 808 pt2[0] = null; 809 line.jiaodian(a, c, pt2, 0); 810 if (pt2[0] != null) 811 if (line.judgeinline(a, pt2[0]) && line.judgeinline(c, pt2[0])) 812 return false; 813 else 814 return true; 815 else 816 return true; 817 } 818 } 819 820 else { 821 Point[] pt2 = new Point[1]; 822 pt2[0] = null; 823 line.jiaodian(a, c, pt2, 0); 824 if (pt2[0] != null) 825 if (line.judgeinline(a, pt2[0])) 826 return false; 827 else 828 return true; 829 else 830 return true; 831 } 832 833 } 834 835 double area() { 836 Point[] pt1 = new Point[3]; 837 pt1[0] = p1; 838 pt1[1] = p2; 839 pt1[2] = p3; 840 841 Point[] pt2 = new Point[3]; 842 pt2[0] = p1; 843 pt2[1] = p2; 844 pt2[2] = p4; 845 846 Point[] pt3 = new Point[3]; 847 pt3[0] = p1; 848 pt3[1] = p4; 849 pt3[2] = p3; 850 851 Point[] pt4 = new Point[3]; 852 pt4[0] = p3; 853 pt4[1] = p2; 854 pt4[2] = p4; 855 856 triangle s1 = new triangle(pt3); 857 triangle s2 = new triangle(pt1); 858 triangle s3 = new triangle(pt2); 859 triangle s4 = new triangle(pt4); 860 861 double area1 = s1.area() + s2.area(); 862 double area2 = s3.area() + s4.area(); 863 if (area1 >= area2) 864 return area2; 865 else 866 return area1; 867 868 } 869 870 double zhouchang() { 871 return a.length + b.length + c.length + d.length; 872 } 873 874 boolean pxsbx() { 875 if (line.judgepinxing(a, c) && line.judgepinxing(d, b)) 876 return true; 877 else 878 return false; 879 } 880 881 String l_j_z(sibian e) { 882 String s; 883 if (e.pxsbx()) { 884 line l1 = new line(p3, p1); 885 line l2 = new line(p2, p4); 886 if ((a.length == b.length && c.length == d.length && c.length == b.length) 887 && Math.abs(l1.length - l2.length) < 0.000001) { 888 s = "zfx"; 889 } else { 890 if (a.length == b.length && c.length == d.length && c.length == b.length) 891 s = "lx"; 892 else if (Math.abs(l1.length - l2.length) < 0.000001) 893 s = "jx"; 894 else 895 s = "ptsbx"; 896 897 } 898 899 } else 900 s = "ptsbx"; 901 return s; 902 } 903 904 String tuorao() { 905 String s = ""; 906 double z1, z2, z3, z4; 907 z1 = ((p2.x - p1.x) * (p4.y - p1.y) - (p4.x - p1.x) * (p2.y - p1.y)); 908 z2 = ((p4.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p4.y - p1.y)); 909 z3 = ((p4.x - p2.x) * (p3.y - p2.y) - (p3.x - p2.x) * (p4.y - p2.y)); 910 z4 = ((p3.x - p2.x) * (p1.y - p2.y) - (p1.x - p2.x) * (p3.y - p2.y)); 911 if (z1 * z2 * z3 * z4 > 0) 912 s = "true"; 913 else 914 s = "false"; 915 916 return s; 917 } 918 919 int sanjiaoxing() { 920 int flag = 0; 921 if (Point.judgeeq(p1, p2) || Point.judgeeq(p1, p3) || Point.judgeeq(p1, p4) || Point.judgeeq(p2, p3) 922 || Point.judgeeq(p2, p4) || Point.judgeeq(p3, p4)) { 923 Point[] pt1 = new Point[3]; 924 if (Point.judgeeq(p1, p2)) { 925 pt1[0] = p1; 926 pt1[1] = p3; 927 pt1[2] = p4; 928 flag = 1; 929 } else if (Point.judgeeq(p1, p3)) { 930 pt1[0] = p1; 931 pt1[1] = p2; 932 pt1[2] = p4; 933 flag = 2; 934 } else if (Point.judgeeq(p1, p4)) { 935 pt1[0] = p1; 936 pt1[1] = p3; 937 pt1[2] = p2; 938 flag = 3; 939 } else if (Point.judgeeq(p3, p2)) { 940 pt1[0] = p1; 941 pt1[1] = p3; 942 pt1[2] = p4; 943 flag = 4; 944 } else if (Point.judgeeq(p4, p2)) { 945 pt1[0] = p1; 946 pt1[1] = p3; 947 pt1[2] = p4; 948 flag = 5; 949 } else if (Point.judgeeq(p4, p3)) { 950 pt1[0] = p1; 951 pt1[1] = p2; 952 pt1[2] = p4; 953 flag = 6; 954 } 955 triangle sTriangle = new triangle(pt1); 956 if (!sTriangle.can_triangle()) 957 flag = 0; 958 959 } else { 960 Point[] pt1 = new Point[3]; 961 pt1[0] = p1; 962 pt1[1] = p2; 963 pt1[2] = p3; 964 line l1 = new line(p1, p3); 965 966 Point[] pt2 = new Point[3]; 967 pt2[0] = p1; 968 pt2[1] = p2; 969 pt2[2] = p4; 970 line l2 = new line(p2, p4); 971 972 Point[] pt3 = new Point[3]; 973 pt3[0] = p1; 974 pt3[1] = p4; 975 pt3[2] = p3; 976 line l3 = new line(p3, p1); 977 978 Point[] pt4 = new Point[3]; 979 pt4[0] = p2; 980 pt4[1] = p4; 981 pt4[2] = p3; 982 line l4 = new line(p4, p2); 983 984 if (line.judgegonxian(pt1) && !l1.judgein_line(p4) && line.judgeinline(l1, p2)) { 985 flag = 7; 986 987 } else if (line.judgegonxian(pt2) && !l2.judgein_line(p3) && line.judgeinline(l2, p1)) { 988 flag = 8; 989 990 } else if (line.judgegonxian(pt3) && !l3.judgein_line(p2) && line.judgeinline(l3, p4)) { 991 flag = 9; 992 993 } else if (line.judgegonxian(pt4) && !l4.judgein_line(p1) && line.judgeinline(l4, p3)) { 994 flag = 10; 995 996 } else { 997 flag = 0; 998 } 999 } 1000 return flag; 1001 } 1002 1003 }
(3)题目3
7-3 设计一个银行业务类
编写一个银行业务类BankBusiness,具有以下属性和方法: (1)公有、静态的属性:银行名称bankName,初始值为“中国银行”。 (2)私有属性:账户名name、密码password、账户余额balance。 (3)银行对用户到来的欢迎(welcome)动作(静态、公有方法),显示“中国银行欢迎您的到来!”,其中“中国银行”自动使用bankName的值。 (4)银行对用户离开的提醒(welcomeNext)动作(静态、公有方法),显示“请收好您的证件和物品,欢迎您下次光临!” (5)带参数的构造方法,完成开户操作。需要账户名name、密码password信息,同时让账户余额为0。 (6)用户的存款(deposit)操作(公有方法,需要密码和交易额信息),密码不对时无法存款且提示“您的密码错误!”;密码正确、完成用户存款操作后,要提示用户的账户余额,例如“您的余额有1000.0元。”。 (7)用户的取款(withdraw)操作(公有方法,需要密码和交易额信息)。密码不对时无法取款且提示“您的密码错误!”;密码正确但余额不足时提示“您的余额不足!”;密码正确且余额充足时扣除交易额并提
示用户的账户余额,例如“请取走钞票,您的余额还有500.0元。”。
输入格式:
输入开户需要的姓名、密码
输入正确密码、存款金额
输入错误密码、取款金额
输入正确密码、大于余额的取款金额
输入正确密码、小于余额的取款金额
输出格式:
中国银行(银行名称)欢迎您的到来!
您的余额有多少元。
您的密码错误!
您的余额不足!
请取走钞票,您的余额还有多少元。
请收好您的证件和物品,欢迎您下次光临!
输入样例:
在这里给出一组输入。请注意,输入与输出是交替的,具体顺序请看测试类中的说明。例如:
张三 123456
123456 1000
654321 2000
123456 2000
123456 500
输出样例:
在这里给出相应的输出。请注意,输入与输出是交替的,具体顺序请看测试类中的说明。例如:
中国银行欢迎您的到来!
您的余额有1000.0元。
您的密码错误!
您的余额不足!
请取走钞票,您的余额还有500.0元。
请收好您的证件和物品,欢迎您下次光临!
-
设计与分析
圈复杂度:
这道题目简单,直接给出圈复杂度分析图和类图。
类图:
-
踩坑心得
就一个需要注意的地方。在接受字符串的时候用in.next(),因为它要接受以空格为分界的字符串。
-
改进建议
没有。
-
源码附录

1 import java.util.Scanner; 2 3 public class Main{ 4 5 public static void main(String[] args) { 6 BankBusiness.welcome(); 7 Scanner in = new Scanner(System.in); 8 String name = in.next(); 9 int passward = in.nextInt(); 10 BankBusiness account = new BankBusiness(name, passward); 11 12 int passward1 = in.nextInt(); 13 double x1 = in.nextDouble(); 14 account.deposit(passward1, x1); 15 16 int passward2 = in.nextInt(); 17 double x2 = in.nextDouble(); 18 account.withdraw(passward2, x2); 19 20 int passward3 = in.nextInt(); 21 double x3 = in.nextDouble(); 22 account.withdraw(passward3, x3); 23 24 int passward4 = in.nextInt(); 25 double x4 = in.nextDouble(); 26 account.withdraw(passward4, x4); 27 28 BankBusiness.welcomenext(); 29 30 } 31 } 32 33 class BankBusiness { 34 public static String bankname = "中国银行"; 35 private String name; 36 private int password; 37 private double balance; 38 39 BankBusiness(String name1, int password1) { 40 name = name1; 41 password = password1; 42 balance = 0.0; 43 } 44 45 public static void welcome() { 46 System.out.println("中国银行欢迎您的到来!"); 47 48 } 49 50 public static void welcomenext() { 51 System.out.println("请收好您的证件和物品,欢迎您下次光临!"); 52 53 } 54 55 public void deposit(int password1, double x) { 56 if (password1 != password) { 57 System.out.println("您的密码错误!"); 58 return; 59 } else { 60 balance = balance + x; 61 System.out.println("您的余额有" + balance + "元。"); 62 } 63 } 64 65 public void withdraw(int password1, double x) { 66 if (password1 != password) { 67 System.out.println("您的密码错误!"); 68 return; 69 } else { 70 if (x > balance) { 71 System.out.println("您的余额不足!"); 72 return; 73 } 74 balance = balance - x; 75 System.out.println("请取走钞票,您的余额还有" + balance + "元。"); 76 } 77 } 78 79 }
PTA第五次大作业
(1)题目1
7-1 点线形系列5-凸五边形的计算-1
用户输入一组选项和数据,进行与五边形有关的计算。 以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。 选项包括: 1:输入五个点坐标,判断是否是五边形,判断结果输出true/false。 2:输入五个点坐标,判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周长、面积,结果之间以一个英文空格符分隔。 若五个点坐标无法构成五边形,输出
"not a pentagon" 3:输入七个点坐标,前两个点构成一条直线,后五个点构成一个凸五边形、凸四边形或凸三角形,输出直线与五边形、四边形或三角形相交的交点数量。如果交点有两个,再按面积从小到大输出被直线分割成两部
分的面积(不换行)。若直线与多边形形的一条边线重合,输出"The line is coincide with one of the lines"。若后五个点不符合五边形输入,若前两点重合,输出"points coincide"。 以上3选项中,若输入的点无法构成多边形,则输出"not a polygon"。输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s: 1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。 2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。 异常情况输出: 如果不符合基本格式,输出"Wrong Format"。 如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。 注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为
1.0
详细信息及样例请查看附件,本题包含附件中的选项1-3的功能:
https://images.ptausercontent.com/d051549e-7cf6-416b-aa9f-25cb521a7ff1.pdf
-
设计与分析
圈复杂度分析图:
类图:
这道题目难度较大,而且复杂,它五个点要形成四边形、三角形考虑的情况很多,重复点,中间点的情况也很多,一开始类的属性没用数组导致没有办法很好的遍历找到中间点以及重复点去去除中间点和重复点,为了沿用之前写的代码我就直接将所有可能的情况都通过条件判断语句去实现了。
难点:
五个点形成四边形、三角形。(去掉重复点,去掉中间点)。
情况1:
判断能否成为五边形,用的还是相邻的边不共线,不相邻的边不相交。
情况2:
用的还是叉乘的方法去判断凸凹边形,求面积还是分割。这里只考虑凸五边形的面积计算,所有没有什么特殊情况。
情况3:
在判断完能成为的图形类型后,如果是三角形和四边形采用原先代码。如果是五边形的情况:
-
踩坑心得
坑点1:这道题目的难点就是判断五个点可以形成三角形和四边形的情况,它的情况很多种,也很复杂,因为我是用的穷举法,算是,所以就会很容易忽略掉部分情况。
坑点2:判断交点情况中,一开始忽略了一些情况导致部分测试点过不去。
-
改进建议
圈复杂度分析图来看无疑这道题目的代码质量不高,可读性差。这道题目难度较大,而且复杂,它五个点要形成四边形、三角形考虑的情况很多,重复点,中间点的情况也很多,一开始类的属性没用数组导致没有办法很好的遍历找到中间点以及重复点去去除中间点和重复点,为了沿用之前写的代码我就直接将所有可能的情况都通过条件判断语句去实现了,这无疑就增加了圈复杂度,之前就提到过解构的方法,还有就是提炼出相同的作用改写成方法去调用来减少圈复杂度。以及类图的设计,还有就是三角形、四边形、五边形就可以考虑写个父类,采用继承和多态来编程设计。
-
源码附录

1 import java.text.DecimalFormat; 2 import java.util.Scanner; 3 4 public class MOOC_text { 5 public static void main(String[] args) { 6 Scanner in = new Scanner(System.in); 7 String str1 = in.nextLine(); 8 char ch1 = str1.charAt(0); 9 char ch2 = str1.charAt(1); 10 String str = str1.substring(2); 11 if (ch2 != ':') { 12 System.out.println("Wrong Format"); 13 return; 14 } 15 switch (ch1) { 16 case '1': { 17 int n = 5; 18 Point[] p = new Point[n]; 19 int shuling = Point.getp(str, p, n); 20 if (shuling == 1) { 21 pentagon wbx = new pentagon(p); 22 if (wbx.is_pentagon()) 23 System.out.println("true"); 24 else 25 System.out.println("false"); 26 } else if (shuling != 1 && shuling != -1) { 27 System.out.println("wrong number of points"); 28 } 29 break; 30 } 31 case '2': { 32 int n = 5; 33 Point[] p = new Point[n]; 34 int shuling = Point.getp(str, p, n); 35 DecimalFormat df = new DecimalFormat("0.0##"); 36 if (shuling == 1) { 37 pentagon wbx = new pentagon(p); 38 if (wbx.is_pentagon()) { 39 if (!wbx.tuorao()) 40 System.out.print("false"); 41 else { 42 System.out.print("true "); 43 System.out.println(df.format(wbx.zhouchang()) + " " + df.format(wbx.area())); 44 } 45 } else 46 System.out.println("not a pentagon"); 47 48 } else if (shuling != 1 && shuling != -1) { 49 System.out.println("wrong number of points"); 50 } 51 break; 52 } 53 case '3': { 54 int n = 7; 55 Point[] p = new Point[n]; 56 int shuling = Point.getp(str, p, n); 57 DecimalFormat df = new DecimalFormat("0.0##"); 58 if (shuling == 1) { 59 line l = new line(p[0], p[1]); 60 if (Point.judgeeq(p[0], p[1])) 61 System.out.println("points coincide"); 62 else { 63 Point[] pt2 = new Point[5]; 64 pt2[0] = p[2]; 65 pt2[1] = p[3]; 66 pt2[2] = p[4]; 67 pt2[3] = p[5]; 68 pt2[4] = p[6]; 69 pentagon wbx = new pentagon(pt2); 70 triangle[] sanTriangle = new triangle[1]; 71 sibian[] sb1 = new sibian[1]; 72 if (wbx.is_sanjiao(sanTriangle)) { 73 if (line.judgechonghe(l, sanTriangle[0].a) || line.judgechonghe(l, sanTriangle[0].b) 74 || line.judgechonghe(l, sanTriangle[0].c)) { 75 System.out.println("The line is coincide with one of the lines"); 76 } else { 77 int count = 0; 78 Point[] jd = new Point[3]; 79 line[] jx = new line[3]; 80 if (line.jiaodian(sanTriangle[0].a, l, jd, count)) { 81 82 jx[count] = sanTriangle[0].a; 83 count++; 84 85 } 86 if (line.jiaodian(sanTriangle[0].b, l, jd, count)) { 87 88 jx[count] = sanTriangle[0].b; 89 count++; 90 } 91 if (line.jiaodian(sanTriangle[0].c, l, jd, count)) { 92 93 jx[count] = sanTriangle[0].c; 94 count++; 95 } 96 97 if (count < 2) 98 System.out.println(count); 99 else if (count == 2) { 100 double area1, area2; 101 if (jd[1].x == jd[0].x && jd[0].y == jd[1].y) 102 System.out.println(count - 1); 103 else { 104 line.jiaodian(jx[0], jx[1], jd, 2); 105 triangle tri = new triangle(jd); 106 area1 = tri.area(); 107 area2 = sanTriangle[0].area() - tri.area(); 108 double max, min; 109 if (area1 > area2) { 110 max = area1; 111 min = area2; 112 113 } else { 114 max = area2; 115 min = area1; 116 } 117 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 118 } 119 120 } else { 121 double area1, area2; 122 if (jd[0].x == jd[1].x && jd[0].y == jd[1].y) { 123 jd[1].x = jd[2].x; 124 jd[1].y = jd[2].y; 125 line.jiaodian(jx[0], jx[2], jd, 2); 126 } 127 128 if (jd[0].x == jd[2].x && jd[0].y == jd[2].y) { 129 line.jiaodian(jx[0], jx[1], jd, 2); 130 } 131 132 if (jd[2].x == jd[1].x && jd[2].y == jd[1].y) { 133 line.jiaodian(jx[0], jx[2], jd, 2); 134 } 135 136 triangle tri = new triangle(jd); 137 area1 = tri.area(); 138 area2 = sanTriangle[0].area() - tri.area(); 139 double max, min; 140 if (area1 > area2) { 141 max = area1; 142 min = area2; 143 144 } else { 145 max = area2; 146 min = area1; 147 } 148 count--; 149 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 150 } 151 152 } 153 } else if (wbx.is_sibian(pt2, sb1)) { 154 if (line.judgechonghe(l, sb1[0].a) || line.judgechonghe(l, sb1[0].b) 155 || line.judgechonghe(l, sb1[0].c) || line.judgechonghe(l, sb1[0].d)) 156 System.out.println("The line is coincide with one of the lines"); 157 else { 158 int count = 0; 159 Point[] jd = new Point[4]; 160 line[] jx = new line[4]; 161 if (line.jiaodian(sb1[0].a, l, jd, count)) { 162 163 jx[count] = sb1[0].a; 164 count++; 165 166 } 167 if (line.jiaodian(sb1[0].b, l, jd, count)) { 168 169 jx[count] = sb1[0].b; 170 count++; 171 } 172 if (line.jiaodian(sb1[0].c, l, jd, count)) { 173 174 jx[count] = sb1[0].c; 175 count++; 176 } 177 if (line.jiaodian(sb1[0].d, l, jd, count)) { 178 179 jx[count] = sb1[0].d; 180 count++; 181 } 182 double area1, area2; 183 if (count < 2) 184 System.out.println(count); 185 else if (count == 2) { 186 187 if (jd[0].x == jd[1].x && jd[0].y == jd[1].y) 188 System.out.println(count - 1); 189 else { 190 line.jiaodian(jx[0], jx[1], jd, 2); 191 if (!line.jiaodian(jx[0], jx[1], jd, 2)) { 192 Point[] pp1 = new Point[4]; 193 if (jx[0] == sb1[0].a && jx[1] == sb1[0].c) { 194 195 pp1[0] = jd[0]; 196 pp1[1] = sb1[0].p2; 197 pp1[2] = sb1[0].p3; 198 pp1[3] = jd[1]; 199 } else { 200 201 pp1[0] = sb1[0].p1; 202 pp1[1] = sb1[0].p2; 203 pp1[2] = jd[0]; 204 pp1[3] = jd[1]; 205 } 206 sibian sb2 = new sibian(pp1); 207 area1 = sb2.area(); 208 area2 = sb1[0].area() - sb2.area(); 209 double max, min; 210 if (area1 > area2) { 211 max = area1; 212 min = area2; 213 214 } else { 215 max = area2; 216 min = area1; 217 } 218 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 219 220 } else { 221 triangle tri = new triangle(jd); 222 area1 = tri.area(); 223 area2 = sb1[0].area() - tri.area(); 224 double max, min; 225 if (area1 > area2) { 226 max = area1; 227 min = area2; 228 229 } else { 230 max = area2; 231 min = area1; 232 } 233 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 234 } 235 } 236 237 } else if (count == 3) { 238 Point[] pp1 = new Point[3]; 239 if (Point.judgeeq(jd[0], sb1[0].p1) && Point.judgeeq(jd[2], sb1[0].p1)) { 240 if (jx[1] == sb1[0].b) { 241 pp1[0] = sb1[0].p1; 242 pp1[1] = sb1[0].p2; 243 pp1[2] = jd[1]; 244 } else { 245 pp1[0] = sb1[0].p1; 246 pp1[1] = sb1[0].p4; 247 pp1[2] = jd[1]; 248 } 249 } else if (Point.judgeeq(jd[0], sb1[0].p2) && Point.judgeeq(jd[1], sb1[0].p2)) { 250 if (jx[1] == sb1[0].c) { 251 pp1[0] = sb1[0].p3; 252 pp1[1] = sb1[0].p2; 253 pp1[2] = jd[2]; 254 } else { 255 pp1[0] = sb1[0].p1; 256 pp1[1] = sb1[0].p2; 257 pp1[2] = jd[2]; 258 } 259 } else if ((Point.judgeeq(jd[0], sb1[0].p3) && Point.judgeeq(jd[1], sb1[0].p3)) 260 || (Point.judgeeq(jd[1], sb1[0].p3) && Point.judgeeq(jd[2], sb1[0].p3))) { 261 if (jx[1] == sb1[0].a) { 262 pp1[0] = sb1[0].p3; 263 pp1[1] = sb1[0].p2; 264 pp1[2] = jd[0]; 265 } else { 266 pp1[0] = sb1[0].p3; 267 pp1[1] = sb1[0].p4; 268 pp1[2] = jd[2]; 269 } 270 } else { 271 if (jx[0] == sb1[0].a) { 272 pp1[0] = sb1[0].p1; 273 pp1[1] = sb1[0].p4; 274 pp1[2] = jd[0]; 275 } else { 276 pp1[0] = sb1[0].p4; 277 pp1[1] = sb1[0].p3; 278 pp1[2] = jd[0]; 279 } 280 } 281 triangle tri = new triangle(pp1); 282 area1 = tri.area(); 283 area2 = sb1[0].area() - tri.area(); 284 double max, min; 285 if (area1 > area2) { 286 max = area1; 287 min = area2; 288 289 } else { 290 max = area2; 291 min = area1; 292 } 293 System.out.println("2" + " " + df.format(min) + " " + df.format(max)); 294 295 } else { 296 Point[] pp = new Point[3]; 297 if (jd[0].x == sb1[0].p2.x && jd[0].y == sb1[0].p2.y) { 298 pp[0] = sb1[0].p1; 299 pp[1] = sb1[0].p2; 300 pp[2] = sb1[0].p4; 301 } else { 302 pp[0] = sb1[0].p1; 303 pp[1] = sb1[0].p2; 304 pp[2] = sb1[0].p3; 305 } 306 triangle tri = new triangle(pp); 307 area1 = tri.area(); 308 area2 = sb1[0].area() - tri.area(); 309 double max, min; 310 if (area1 > area2) { 311 max = area1; 312 min = area2; 313 314 } else { 315 max = area2; 316 min = area1; 317 } 318 System.out.println("2" + " " + df.format(min) + " " + df.format(max)); 319 } 320 321 } 322 } else if (wbx.is_pentagon()) { 323 if (line.judgechonghe(l, wbx.a) || line.judgechonghe(l, wbx.b) || line.judgechonghe(l, wbx.c) 324 || line.judgechonghe(l, wbx.d) || line.judgechonghe(l, wbx.e)) 325 System.out.println("The line is coincide with one of the lines"); 326 else { 327 int count = 0; 328 Point[] jd = new Point[4]; 329 line[] jx = new line[4]; 330 if (line.jiaodian(wbx.a, l, jd, count)) { 331 332 jx[count] = wbx.a; 333 count++; 334 335 } 336 if (line.jiaodian(wbx.b, l, jd, count)) { 337 338 jx[count] = wbx.b; 339 count++; 340 } 341 if (line.jiaodian(wbx.c, l, jd, count)) { 342 343 jx[count] = wbx.c; 344 count++; 345 } 346 if (line.jiaodian(wbx.d, l, jd, count)) { 347 348 jx[count] = wbx.d; 349 count++; 350 } 351 if (line.jiaodian(wbx.e, l, jd, count)) { 352 353 jx[count] = wbx.e; 354 count++; 355 } 356 double area1, area2; 357 if (count < 2) 358 System.out.println(count); 359 if (count == 2) { 360 if (jd[0].x == jd[1].x && jd[0].y == jd[1].y) 361 System.out.println(count - 1); 362 else { 363 line.jiaodian(jx[0], jx[1], jd, 2); 364 if (jd[2] == null || !line.jiaodian(jx[0], jx[1], jd, 2)) { 365 Point[] pp1 = new Point[4]; 366 367 sibian sb2 = new sibian(pp1); 368 area1 = sb2.area(); 369 area2 = wbx.area() - sb2.area(); 370 double max, min; 371 if (area1 > area2) { 372 max = area1; 373 min = area2; 374 375 } else { 376 max = area2; 377 min = area1; 378 } 379 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 380 381 } else { 382 triangle tri = new triangle(jd); 383 area1 = tri.area(); 384 area2 = sb1[0].area() - tri.area(); 385 double max, min; 386 if (area1 > area2) { 387 max = area1; 388 min = area2; 389 390 } else { 391 max = area2; 392 min = area1; 393 } 394 System.out.println(count + " " + df.format(min) + " " + df.format(max)); 395 } 396 } 397 } 398 if (count == 3) { 399 if (Point.judgeeq(jd[0], jd[1])) 400 jd[1] = jd[2]; 401 } 402 if (count == 4) { 403 Point[] pp = new Point[3]; 404 if (Point.judgeeq(jd[0], wbx.p1) && Point.judgeeq(jd[1], wbx.p3)) { 405 pp[0] = wbx.p1; 406 pp[1] = wbx.p2; 407 pp[2] = wbx.p3; 408 } 409 410 if (Point.judgeeq(jd[0], wbx.p1) && Point.judgeeq(jd[1], wbx.p4)) { 411 pp[0] = wbx.p1; 412 pp[1] = wbx.p4; 413 pp[2] = wbx.p5; 414 } 415 416 if (Point.judgeeq(jd[0], wbx.p2) && Point.judgeeq(jd[2], wbx.p4)) { 417 pp[0] = wbx.p2; 418 pp[1] = wbx.p3; 419 pp[2] = wbx.p4; 420 } 421 422 if (Point.judgeeq(jd[0], wbx.p2) && Point.judgeeq(jd[2], wbx.p5)) { 423 pp[0] = wbx.p1; 424 pp[1] = wbx.p2; 425 pp[2] = wbx.p5; 426 } 427 428 if (Point.judgeeq(jd[0], wbx.p3) && Point.judgeeq(jd[2], wbx.p5)) { 429 pp[0] = wbx.p3; 430 pp[1] = wbx.p4; 431 pp[2] = wbx.p5; 432 } 433 434 triangle tri = new triangle(pp); 435 area1 = tri.area(); 436 area2 = wbx.area() - tri.area(); 437 double max, min; 438 if (area1 > area2) { 439 max = area1; 440 min = area2; 441 442 } else { 443 max = area2; 444 min = area1; 445 } 446 System.out.println("2" + " " + df.format(min) + " " + df.format(max)); 447 } 448 } 449 450 } else 451 System.out.println("not a polygon"); 452 453 } 454 } else if (shuling != -1) { 455 System.out.println("wrong number of points"); 456 } 457 break; 458 } 459 default: 460 System.out.println("Wrong Format"); 461 break; 462 } 463 464 } 465 } 466 467 class Point { 468 double x, y; 469 470 Point(String x1, String y1) { 471 x = Double.valueOf(x1); 472 y = Double.valueOf(y1); 473 } 474 475 double getdistan(Point p) { 476 double t = Math.sqrt(Math.pow(x - p.x, 2) + Math.pow(y - p.y, 2)); 477 return t; 478 } 479 480 static Boolean judge(String str) { 481 if (!str.matches("^[+-]?(0|(0\\.[\\d]+)?|[1-9][0-9]*(\\.[\\d]+)?)$")) { 482 return false; 483 } else 484 return true; 485 486 } 487 488 static int getp(String str, Point[] p, int sizE) 489 490 { 491 int count = 0; 492 int m = 0; 493 String[] A = str.split(" "); 494 for (String B : A) { 495 int i = 0; 496 String[] C = B.split(","); 497 if (C.length != 2) { 498 System.out.println("Wrong Format"); 499 return -1; 500 } 501 String[] num = B.split(","); 502 for (String D : C) { 503 504 if (!Point.judge(C[i])) { 505 System.out.println("Wrong Format"); 506 return -1; 507 } 508 num[i] = D; 509 i++; 510 } 511 if (m < sizE && i == 2) { 512 p[m] = new Point(num[0], num[1]); 513 m++; 514 } 515 516 count++; 517 } 518 if (count == sizE) 519 return 1; 520 else 521 return count; 522 523 } 524 525 static boolean judgeeq(Point p1, Point p2) { 526 if (p1.x == p2.x && p1.y == p2.y) 527 return true; 528 else 529 return false; 530 } 531 532 static boolean judgeeq2(Point p1, Point p2, Point p3) { 533 if (Point.judgeeq(p1, p2) && Point.judgeeq(p1, p3)) 534 return true; 535 else 536 return false; 537 } 538 539 } 540 541 class line { 542 Point p1; 543 Point p2; 544 double k; 545 double length; 546 547 line(Point a, Point b) { 548 p1 = a; 549 p2 = b; 550 if (p1.x != p2.x) 551 k = (p2.y - p1.y) / (p2.x - p1.x); 552 length = a.getdistan(b); 553 } 554 555 boolean xielv() { 556 557 if (p1.x == p2.x) 558 return false; 559 else 560 return true; 561 } 562 563 static boolean judgepinxing(line a, line b) { 564 if (!a.xielv() && !b.xielv()) 565 return true; 566 else if (a.xielv() && b.xielv()) { 567 if (a.k == b.k) 568 return true; 569 else 570 return false; 571 } else 572 return false; 573 574 } 575 576 // 判断三点共线 577 static boolean judgegonxian(Point[] p) { 578 if (!Point.judgeeq(p[0], p[1]) && !Point.judgeeq(p[2], p[1]) && !Point.judgeeq(p[0], p[2])) { 579 line p1 = new line(p[0], p[1]); 580 line p2 = new line(p[1], p[2]); 581 if (p1.xielv() && p2.xielv()) { 582 if (p1.k == p2.k) { 583 return true; 584 } else 585 return false; 586 } else if ((p1.xielv() && !p2.xielv()) || (!p1.xielv() && p2.xielv())) 587 return false; 588 else if (p[0].x == p[1].x && p[1].x == p[2].x) { 589 return true; 590 } else { 591 return false; 592 } 593 } else 594 595 { 596 return true; 597 } 598 599 } 600 601 // 判断四点共线 602 static boolean judgegonxian1(Point p1, Point p2, Point p3, Point p4) { 603 Point[] p = new Point[3]; 604 p[0] = p1; 605 p[1] = p2; 606 p[2] = p3; 607 if (line.judgegonxian(p)) { 608 line l = new line(p1, p3); 609 if (p1.equals(p3)) 610 l.p2 = p2; 611 if (l.judgein_line(p4)) 612 return true; 613 else 614 return false; 615 } else 616 return false; 617 618 } 619 620 static boolean judgeinline(line a, Point p) { 621 double max1, min1; 622 if (a.p1.x > a.p2.x) { 623 max1 = a.p1.x; 624 min1 = a.p2.x; 625 } else { 626 max1 = a.p2.x; 627 min1 = a.p1.x; 628 } 629 630 double max2, min2; 631 if (a.p1.y > a.p2.y) { 632 max2 = a.p1.y; 633 min2 = a.p2.y; 634 } else { 635 max2 = a.p2.y; 636 min2 = a.p1.y; 637 } 638 if ((p.x < max1 && p.x > min1) || Math.abs(p.x - max1) < 0.000001 || Math.abs(p.x - min1) < 0.000001) { 639 if ((p.y < max2 && p.y > min2) || Math.abs(p.y - max2) < 0.000001 || Math.abs(p.y - min2) < 0.000001) 640 return true; 641 else 642 return false; 643 } else 644 return false; 645 } 646 647 static boolean jiaodian(line a, line b, Point[] jd, int count) { 648 double x = 0, y = 0, A1, B1, C1, A2, B2, C2; 649 if (line.judgepinxing(a, b)) 650 return false; 651 if (a.xielv() && b.xielv()) { 652 653 A1 = a.p1.y - a.p2.y; 654 B1 = a.p2.x - a.p1.x; 655 C1 = (a.p2.y - a.p1.y) * a.p1.x - (a.p2.x - a.p1.x) * a.p1.y; 656 A2 = b.p1.y - b.p2.y; 657 B2 = b.p2.x - b.p1.x; 658 C2 = (b.p2.y - b.p1.y) * b.p1.x - (b.p2.x - b.p1.x) * b.p1.y; 659 x = (B1 * C2 - B2 * C1) / (A1 * B2 - A2 * B1); 660 y = (A1 * C2 - A2 * C1) / (B1 * A2 - B2 * A1); 661 662 } else if (a.xielv() && !b.xielv()) { 663 x = b.p1.x; 664 y = a.p1.y + ((b.p1.x - a.p1.x) * (a.p2.y - a.p1.y) / (a.p2.x - a.p1.x)); 665 666 } else if (!a.xielv() && b.xielv()) { 667 x = a.p1.x; 668 y = b.p1.y + ((a.p1.x - b.p1.x) * (b.p2.y - b.p1.y) / (b.p2.x - b.p1.x)); 669 670 } 671 String x1 = "".valueOf(x); 672 String y1 = "".valueOf(y); 673 jd[count] = new Point(x1, y1); 674 if (line.judgeinline(a, jd[count])) 675 return true; 676 else 677 return false; 678 679 } 680 681 static boolean judgechonghe(line a, line b) { 682 if (line.judgepinxing(a, b) && a.judgein_line(b.p1)) 683 return true; 684 else 685 return false; 686 687 } 688 689 boolean judgein_line(Point p) { 690 double A, B, C; 691 A = p1.y - p2.y; 692 B = p2.x - p1.x; 693 C = (p2.y - p1.y) * p1.x - (p2.x - p1.x) * p1.y; 694 if ((A * p.x + B * p.y + C) == 0) 695 return true; 696 else { 697 return false; 698 } 699 } 700 701 // 判断两条线段有无交点 702 static boolean have_jiaodian(line a, line b) { 703 Point[] jd = new Point[2]; 704 if (line.jiaodian(a, b, jd, 0) && line.jiaodian(b, a, jd, 1)) 705 return true; 706 else 707 return false; 708 709 } 710 711 } 712 713 class triangle { 714 Point p1, p2, p3; 715 line a, b, c; 716 717 triangle(Point[] p) { 718 p1 = p[0]; 719 p2 = p[1]; 720 p3 = p[2]; 721 a = new line(p[0], p[1]); 722 b = new line(p[0], p[2]); 723 c = new line(p[1], p[2]); 724 } 725 726 double zhouchang() { 727 double zc = a.length + b.length + c.length; 728 return zc; 729 730 } 731 732 double area() { 733 double area; 734 double p = (a.length + b.length + c.length) / 2.0; 735 area = Math.sqrt(p * (p - a.length) * (p - b.length) * (p - c.length)); 736 return area; 737 } 738 739 boolean can_triangle() { 740 if (!Point.judgeeq(p1, p2) && !Point.judgeeq(p3, p2) && !Point.judgeeq(p1, p3)) { 741 Point[] p = new Point[3]; 742 p[0] = p1; 743 p[1] = p2; 744 p[2] = p3; 745 if (!line.judgegonxian(p)) 746 return true; 747 else 748 return false; 749 } else { 750 return false; 751 } 752 } 753 } 754 755 class sibian { 756 Point p1; 757 Point p2; 758 Point p3; 759 Point p4; 760 line a, b, c, d; 761 762 sibian(Point[] p) { 763 p1 = p[0]; 764 p2 = p[1]; 765 p3 = p[2]; 766 p4 = p[3]; 767 a = new line(p1, p2); 768 b = new line(p2, p3); 769 c = new line(p3, p4); 770 d = new line(p4, p1); 771 } 772 773 boolean is_sibian() { 774 if ((p4.y - p3.y) * (p4.x - p2.x) == (p4.y - p2.y) * (p4.x - p3.x)) 775 return false; 776 else if ((p4.y - p3.y) * (p4.x - p1.x) == (p4.y - p1.y) * (p4.x - p3.x)) 777 return false; 778 else if ((p4.y - p2.y) * (p4.x - p1.x) == (p4.y - p1.y) * (p4.x - p2.x)) 779 return false; 780 else if ((p3.y - p2.y) * (p3.x - p1.x) == (p3.y - p1.y) * (p3.x - p2.x)) 781 return false; 782 Point[] pt1 = new Point[1]; 783 pt1[0] = null; 784 line.jiaodian(b, d, pt1, 0); 785 if (pt1[0] != null) { 786 if (line.judgeinline(b, pt1[0]) && line.judgeinline(d, pt1[0])) 787 return false; 788 else { 789 Point[] pt2 = new Point[1]; 790 pt2[0] = null; 791 line.jiaodian(a, c, pt2, 0); 792 if (pt2[0] != null) 793 if (line.judgeinline(a, pt2[0]) && line.judgeinline(c, pt2[0])) 794 return false; 795 else 796 return true; 797 else 798 return true; 799 } 800 } 801 802 else { 803 Point[] pt2 = new Point[1]; 804 pt2[0] = null; 805 line.jiaodian(a, c, pt2, 0); 806 if (pt2[0] != null) 807 if (line.judgeinline(a, pt2[0])) 808 return false; 809 else 810 return true; 811 else 812 return true; 813 } 814 815 } 816 817 double area() { 818 Point[] pt1 = new Point[3]; 819 pt1[0] = p1; 820 pt1[1] = p2; 821 pt1[2] = p3; 822 823 Point[] pt2 = new Point[3]; 824 pt2[0] = p1; 825 pt2[1] = p2; 826 pt2[2] = p4; 827 828 Point[] pt3 = new Point[3]; 829 pt3[0] = p1; 830 pt3[1] = p4; 831 pt3[2] = p3; 832 833 Point[] pt4 = new Point[3]; 834 pt4[0] = p3; 835 pt4[1] = p2; 836 pt4[2] = p4; 837 838 triangle s1 = new triangle(pt3); 839 triangle s2 = new triangle(pt1); 840 triangle s3 = new triangle(pt2); 841 triangle s4 = new triangle(pt4); 842 843 double area1 = s1.area() + s2.area(); 844 double area2 = s3.area() + s4.area(); 845 if (area1 >= area2) 846 return area2; 847 else 848 return area1; 849 850 } 851 852 double zhouchang() { 853 return a.length + b.length + c.length + d.length; 854 } 855 856 String tuorao() { 857 String s = ""; 858 double z1, z2, z3, z4; 859 z1 = ((p2.x - p1.x) * (p4.y - p1.y) - (p4.x - p1.x) * (p2.y - p1.y)); 860 z2 = ((p4.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p4.y - p1.y)); 861 z3 = ((p4.x - p2.x) * (p3.y - p2.y) - (p3.x - p2.x) * (p4.y - p2.y)); 862 z4 = ((p3.x - p2.x) * (p1.y - p2.y) - (p1.x - p2.x) * (p3.y - p2.y)); 863 if (z1 * z2 * z3 * z4 > 0) 864 s = "true"; 865 else 866 s = "false"; 867 return s; 868 } 869 } 870 871 class pentagon { 872 Point p1, p2, p3, p4, p5; 873 line a, b, c, d, e; 874 875 public pentagon(Point[] p) { 876 p1 = p[0]; 877 p2 = p[1]; 878 p3 = p[2]; 879 p4 = p[3]; 880 p5 = p[4]; 881 a = new line(p1, p2); 882 b = new line(p2, p3); 883 c = new line(p3, p4); 884 d = new line(p4, p5); 885 e = new line(p5, p1); 886 } 887 888 boolean is_pentagon() { 889 if (!line.judgepinxing(a, b) && !line.judgepinxing(c, b) && !line.judgepinxing(c, d) && !line.judgepinxing(d, e) 890 && !line.judgepinxing(a, e)) { 891 892 if (line.have_jiaodian(a, c) || line.have_jiaodian(a, d) || line.have_jiaodian(b, d) 893 || line.have_jiaodian(b, e) || line.have_jiaodian(e, c)) 894 return false; 895 else 896 return true; 897 } else 898 return false; 899 } 900 901 boolean tuorao() { 902 double z1, z2, z3, z4, z5; 903 z1 = ((p1.x - p5.x) * (p2.y - p5.y) - (p2.x - p5.x) * (p1.y - p5.y)); 904 z2 = ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y)); 905 z3 = ((p3.x - p2.x) * (p4.y - p2.y) - (p4.x - p2.x) * (p3.y - p2.y)); 906 z4 = ((p4.x - p3.x) * (p5.y - p3.y) - (p5.x - p3.x) * (p4.y - p3.y)); 907 z5 = ((p5.x - p4.x) * (p1.y - p4.y) - (p1.x - p4.x) * (p5.y - p4.y)); 908 if (z1 > 0 && z2 > 0 && z3 > 0 && z4 > 0 && z5 > 0) 909 return true; 910 else 911 return false; 912 } 913 914 double zhouchang() { 915 return a.length + b.length + c.length + d.length + e.length; 916 } 917 918 double area() { 919 Point[] pp1 = new Point[3]; 920 pp1[0] = p1; 921 pp1[1] = p2; 922 pp1[2] = p5; 923 Point[] pp2 = new Point[4]; 924 pp2[0] = p2; 925 pp2[1] = p3; 926 pp2[2] = p4; 927 pp2[3] = p5; 928 triangle sjx = new triangle(pp1); 929 sibian sbx = new sibian(pp2); 930 return sjx.area() + sbx.area(); 931 } 932 933 // 五个点四边形 934 boolean is_sibian(Point[] p, sibian[] sbx) { 935 int f = 0; 936 for (int i = 1; i < p.length - f; i++) { 937 for (int j = 0; j < i; j++) { 938 if (Point.judgeeq(p[i], p[j])) { 939 for (int k = i; k < p.length - f - 1; k++) { 940 p[k] = p[k + 1]; 941 } 942 f++; 943 } 944 } 945 } 946 if (f == 1) { 947 Point[] pp = new Point[4]; 948 // System.out.println("1"); 949 pp[0] = p[0]; 950 pp[1] = p[1]; 951 pp[2] = p[2]; 952 pp[3] = p[3]; 953 sbx[0] = new sibian(pp); 954 if (sbx[0].is_sibian()) 955 return true; 956 else 957 return false; 958 } else { 959 Point[] ppp = new Point[4]; 960 Point[] pp1 = new Point[3]; 961 pp1[0] = p3; 962 pp1[1] = p4; 963 pp1[2] = p5; 964 line l1 = new line(p3, p5); 965 Point[] pp2 = new Point[3]; 966 pp2[0] = p3; 967 pp2[1] = p4; 968 pp2[2] = p2; 969 line l2 = new line(p2, p4); 970 Point[] pp3 = new Point[3]; 971 pp3[0] = p1; 972 pp3[1] = p4; 973 pp3[2] = p5; 974 line l3 = new line(p1, p4); 975 Point[] pp4 = new Point[3]; 976 pp4[0] = p1; 977 pp4[1] = p2; 978 pp4[2] = p3; 979 line l4 = new line(p1, p3); 980 Point[] pp5 = new Point[3]; 981 pp5[0] = p1; 982 pp5[1] = p2; 983 pp5[2] = p5; 984 line l5 = new line(p5, p2); 985 if (line.judgegonxian(pp1) && line.judgeinline(l1, p4) && !l1.judgein_line(p1) && !l1.judgein_line(p2)) { 986 ppp[0] = p1; 987 ppp[1] = p2; 988 ppp[2] = p3; 989 ppp[3] = p5; 990 } else if (line.judgegonxian(pp2) && line.judgeinline(l2, p3) && !l2.judgein_line(p1) 991 && !l2.judgein_line(p5)) { 992 ppp[0] = p1; 993 ppp[1] = p2; 994 ppp[2] = p4; 995 ppp[3] = p5; 996 } else if (line.judgegonxian(pp3) && line.judgeinline(l3, p5) && !l3.judgein_line(p2) 997 && !l3.judgein_line(p3)) { 998 ppp[0] = p1; 999 ppp[1] = p2; 1000 ppp[2] = p3; 1001 ppp[3] = p4; 1002 } else if (line.judgegonxian(pp4) && line.judgeinline(l4, p2) && !l4.judgein_line(p4) 1003 && !l4.judgein_line(p5)) { 1004 ppp[0] = p1; 1005 ppp[1] = p3; 1006 ppp[2] = p4; 1007 ppp[3] = p5; 1008 } else if (line.judgegonxian(pp5) && line.judgeinline(l5, p1) && !l5.judgein_line(p3) 1009 && !l5.judgein_line(p4)) { 1010 ppp[0] = p2; 1011 ppp[1] = p3; 1012 ppp[2] = p4; 1013 ppp[3] = p5; 1014 } else { 1015 return false; 1016 } 1017 sbx[0] = new sibian(ppp); 1018 if (sbx[0].is_sibian()) 1019 return true; 1020 else 1021 return false; 1022 } 1023 } 1024 1025 // 五个点三角形 1026 boolean is_sanjiao(triangle[] sjx) { 1027 Point[] p = new Point[3]; 1028 Point[] p_1 = new Point[3]; 1029 p_1[0] = p1; 1030 p_1[1] = p2; 1031 p_1[2] = p3; 1032 Point[] p_2 = new Point[3]; 1033 p_2[0] = p2; 1034 p_2[1] = p3; 1035 p_2[2] = p4; 1036 Point[] p_3 = new Point[3]; 1037 p_3[0] = p3; 1038 p_3[1] = p4; 1039 p_3[2] = p5; 1040 Point[] p_4 = new Point[3]; 1041 p_4[0] = p4; 1042 p_4[1] = p5; 1043 p_4[2] = p1; 1044 Point[] p_5 = new Point[3]; 1045 p_5[0] = p5; 1046 p_5[1] = p1; 1047 p_5[2] = p2; 1048 if (Point.judgeeq2(p1, p2, p3)) { 1049 p[0] = p1; 1050 p[1] = p4; 1051 p[2] = p5; 1052 } else if (Point.judgeeq2(p1, p2, p4)) { 1053 p[0] = p1; 1054 p[1] = p3; 1055 p[2] = p5; 1056 } else if (Point.judgeeq2(p1, p2, p5)) { 1057 p[0] = p1; 1058 p[1] = p3; 1059 p[2] = p4; 1060 } else if (Point.judgeeq2(p1, p4, p3)) { 1061 p[0] = p1; 1062 p[1] = p2; 1063 p[2] = p5; 1064 } else if (Point.judgeeq2(p1, p5, p3)) { 1065 p[0] = p1; 1066 p[1] = p2; 1067 p[2] = p4; 1068 } else if (Point.judgeeq2(p1, p4, p5)) { 1069 p[0] = p1; 1070 p[1] = p2; 1071 p[2] = p3; 1072 } else if (Point.judgeeq2(p4, p2, p3)) { 1073 p[0] = p1; 1074 p[1] = p2; 1075 p[2] = p5; 1076 } else if (Point.judgeeq2(p5, p2, p3)) { 1077 p[0] = p1; 1078 p[1] = p2; 1079 p[2] = p4; 1080 } else if (Point.judgeeq2(p4, p2, p5)) { 1081 p[0] = p1; 1082 p[1] = p2; 1083 p[2] = p3; 1084 } else if (Point.judgeeq2(p5, p4, p3)) { 1085 p[0] = p1; 1086 p[1] = p2; 1087 p[2] = p3; 1088 } else if (line.judgegonxian1(p5, p2, p3, p4)) { 1089 line l = new line(p2, p5); 1090 if (line.judgeinline(l, p3) && line.judgeinline(l, p4) && !l.judgein_line(p1)) { 1091 p[0] = p1; 1092 p[1] = p2; 1093 p[2] = p5; 1094 } else 1095 return false; 1096 } else if (line.judgegonxian1(p5, p1, p3, p4)) { 1097 line l = new line(p1, p3); 1098 if (line.judgeinline(l, p4) && line.judgeinline(l, p5) && !l.judgein_line(p2)) { 1099 p[0] = p1; 1100 p[1] = p2; 1101 p[2] = p3; 1102 } else 1103 return false; 1104 } else if (line.judgegonxian1(p5, p2, p1, p4)) { 1105 line l = new line(p2, p1); 1106 if (line.judgeinline(l, p5) && line.judgeinline(l, p4) && !l.judgein_line(p3)) { 1107 p[0] = p1; 1108 p[1] = p2; 1109 p[2] = p3; 1110 } else 1111 return false; 1112 } else if (line.judgegonxian1(p5, p2, p3, p1)) { 1113 line l = new line(p3, p5); 1114 if (line.judgeinline(l, p1) && line.judgeinline(l, p2) && !l.judgein_line(p4)) { 1115 p[0] = p3; 1116 p[1] = p4; 1117 p[2] = p5; 1118 } else 1119 return false; 1120 } else if (line.judgegonxian1(p4, p2, p3, p1)) { 1121 line l = new line(p1, p4); 1122 if (line.judgeinline(l, p2) && line.judgeinline(l, p3) && !l.judgein_line(p5)) { 1123 p[0] = p1; 1124 p[1] = p4; 1125 p[2] = p5; 1126 } else 1127 return false; 1128 } else if (line.judgegonxian(p_1) && line.judgegonxian(p_3)) { 1129 p[0] = p1; 1130 p[1] = p3; 1131 p[2] = p5; 1132 1133 } else if (line.judgegonxian(p_2) && line.judgegonxian(p_4)) { 1134 p[0] = p2; 1135 p[1] = p4; 1136 p[2] = p1; 1137 } else if (line.judgegonxian(p_5) && line.judgegonxian(p_2)) { 1138 p[0] = p2; 1139 p[1] = p4; 1140 p[2] = p5; 1141 } else { 1142 return false; 1143 } 1144 1145 sjx[0] = new triangle(p); 1146 if (sjx[0].can_triangle()) 1147 return true; 1148 else 1149 return false; 1150 } 1151 }
(2)题目2
7-2 点线形系列5-凸五边形的计算-2
用户输入一组选项和数据,进行与五边形有关的计算。 以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。 选项包括: 4:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),判断它们两个之间是否存在包含关系(一个多边形有一条或多条边与另一个多边形重合,其他部分都包含在另一个多边形内
部,也算包含)。 两者存在六种关系:1、分离(完全无重合点) 2、连接(只有一个点或一条边重合) 3、完全重合 4、被包含(前一个多边形在后一个多边形的内部)5、交错 6、包含(后一个多边形在前一个多边形的内部)。 各种关系的输出格式如下: 1、no overlapping area between the previous triangle/quadrilateral/ pentagon and the following triangle/quadrilateral/ pentagon 2、the previous triangle/quadrilateral/ pentagon is connected to the following triangle/quadrilateral/ pentagon 3、the previous triangle/quadrilateral/ pentagon coincides with the following triangle/quadrilateral/ pentagon 4、the previous triangle/quadrilateral/ pentagon is inside the following triangle/quadrilateral/ pentagon 5、the previous triangle/quadrilateral/ pentagon is interlaced with the following triangle/quadrilateral/ pentagon 6、the previous triangle/quadrilateral/ pentagon contains the following triangle/quadrilateral/ pentagon 5:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),输出两个多边形公共区域的面积。注:只考虑每个多边形被另一个多边形分割成最多两个部分的情况,不考虑一个多边形将
另一个分割成超过两个区域的情况。 6:输入六个点坐标,输出第一个是否在后五个点所构成的多边形(限定为凸多边形,不考虑凹多边形),的内部(若是五边形输出in the pentagon/outof the pentagon,若是四边形输出
in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。输入入错存在冗余点要排除,冗余点的判定方法见选项5。如果点在多边形的某条边
上,输出"on the triangle/on the quadrilateral/on the pentagon"。 以上4、5、6选项输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s: 1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。 2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
样例请查看附件:
https://images.ptausercontent.com/68388f4f-d3b9-4d60-bb14-f8ebbcec3d0a.pdf
-
设计与分析
圈复杂度分析图:
类图:
从类图可以看出来,我对上一题的类进行了解构,同时增加了父类。因为随着图形类型的不断增加,重复的功能就增多,例如求面积,周长,判断能否形成某一种图形,判断点在图形的位置,这是每一类图形都要完成的共同功能,所以不妨多写一个图形父类,将这一些共有的方法写在父类中。为了更好的遍历图形的点与线,就直接采用数组来存储点与线。
父类的属性:
构成的点points、构成的线lines、面积area、周长zhouchang、边数(点数)len、能否形成图形can_graphical;
父类的方法:
计算面积、判断周长、构造方法(!!!)、判断点在多边形的位置、判断两个图形的位置关系、求两个图形重叠面积(难点)等。
构造函数:
接收一个points数组,去掉重复点,去掉中间点(采用三点共线且中间点在线段内就去掉该位置的点的方法),判断点的个数,小于3就不能成为图形。
开始初始化边,并且要判断相邻边不平行,不相邻边不相交。
面积和周长调用方法。
求多边形面积:
对于任意的多边形的面积,同样是分割成不同的三角形去求和,考虑到凹多边形的情况,求三角形面积就用向量叉乘。以原点为参考点,相邻顶点p1、p2,求向量op1|、op2的叉乘。依次求出op1、op2;op2、op3......(原理自己搜索相关文章)
判断多边形预点的关系:
面积法。(前面由提)
判断两个图形分离:
点不在对方的边上或图形内部。
判断两个图形一样:
边数相同,且第一个图形的每一个点都能对应第二个图形的点。(!!!不一定是相应下标的点相同)。
判断包含关系:
点全部在另外一个图形内部和线上。
难点:求重叠部分面积
可以看出构成阴影部分面积图形的点是量图形的交点以及原有图形构成的点中在另一个图形内部或者线上的点。
找到了点,怎么求面积?
从图中可以看出来,可以先找到图形的重心,与其中一个顶点构成参考向量p0p1,,不同的向量p0px与p0p1的角度不同,按照角度大小排序(需要用到接口Comparator)得到有序的点集合,这些集合构成一个多边形。
-
踩坑心得
坑点1:初始化边时没有考虑数组大小
坑点2:判断两个图形重合简单的以为是对应下标点一致且边数相同。
坑点3:多考虑了点在线上的情况。
-
改进建议
重构后的类以及提取出的父类大大的降低了代码的圈复杂度,目前没有想到什么需要改进的地方。
-
源码附录

1 import java.util.Arrays; 2 import java.util.Comparator; 3 //import java.text.DecimalFormat; 4 import java.util.Scanner; 5 6 public class Main1 { 7 public static void main(String[] args) { 8 Scanner in = new Scanner(System.in); 9 String str1 = in.nextLine(); 10 char ch1 = str1.charAt(0); 11 char ch2 = str1.charAt(1); 12 String str = str1.substring(2); 13 if (ch2 != ':') { 14 System.out.println("Wrong Format"); 15 return; 16 } 17 switch (ch1) { 18 case '4': { 19 int n = 10; 20 Point[] p = new Point[n]; 21 int shuling = Point.getp(str, p, n); 22 if (shuling == 1) { 23 graphical e1; 24 graphical e2; 25 Point[] p1 = new Point[5]; 26 Point[] p2 = new Point[5]; 27 for (int i = 0; i < 5; i++) 28 p1[i] = p[i]; 29 for (int i = 0; i < 5; i++) 30 p2[i] = p[i + 5]; 31 e1 = new graphical(p1); 32 e2 = new graphical(p2); 33 String[] name = new String[] { "triangle", "quadrilateral", "pentagon" }; 34 if (e1.can_graphical && e2.can_graphical) { 35 // 判断两个图形的关系 36 if (graphical.isseparate(e1, e2)) 37 System.out.println("no overlapping area between the previous " + name[e1.len - 3] 38 + " and the following " + name[e2.len - 3]); 39 else if (graphical.issame(e1, e2)) 40 System.out.println("the previous " + name[e1.len - 3] + " coincides with the following " 41 + name[e2.len - 3]); 42 else if (graphical.iscontaingra(e1, e2)) 43 System.out.println( 44 "the previous " + name[e1.len - 3] + " contains the following " + name[e2.len - 3]); 45 else if (graphical.iscontaingra(e2, e1)) 46 System.out.println( 47 "the previous " + name[e1.len - 3] + " is inside the following " + name[e2.len - 3]); 48 else if (graphical.overlap_area(e1, e2) == 0) 49 System.out.println("the previous " + name[e1.len - 3] + " is connected to the following " 50 + name[e2.len - 3]); 51 else 52 System.out.println("the previous " + name[e1.len - 3] + " is interlaced with the following " 53 + name[e2.len - 3]); 54 } 55 56 } else if (shuling != 1 && shuling != -1) { 57 System.out.println("wrong number of points"); 58 } 59 break; 60 } 61 case '5': { 62 int n = 10; 63 Point[] p = new Point[n]; 64 int shuling = Point.getp(str, p, n); 65 if (shuling == 1) { 66 graphical e1; 67 graphical e2; 68 Point[] p1 = new Point[5]; 69 Point[] p2 = new Point[5]; 70 for (int i = 0; i < 5; i++) 71 p1[i] = p[i]; 72 for (int i = 0; i < 5; i++) 73 p2[i] = p[i + 5]; 74 e1 = new graphical(p1); 75 e2 = new graphical(p2); 76 if (e1.can_graphical && e2.can_graphical) { 77 System.out.println(graphical.overlap_area(e1, e2)); 78 } 79 } else if (shuling != 1 && shuling != -1) { 80 System.out.println("wrong number of points"); 81 } 82 break; 83 } 84 case '6': { 85 int n = 6; 86 Point[] p = new Point[n]; 87 int shuling = Point.getp(str, p, n); 88 if (shuling == 1) { 89 graphical e; 90 Point[] p1 = new Point[5]; 91 for (int i = 0; i < 5; i++) 92 p1[i] = p[i + 1]; 93 e = new graphical(p1); 94 if (e.can_graphical) { 95 String x1 = "".valueOf(p[0].x); 96 String y1 = "".valueOf(p[0].y); 97 Point ppPoint = new Point(x1, y1); 98 String[] name = new String[] { "triangle", "quadrilateral", "pentagon" }; 99 if (e.position(ppPoint).equals("in")) 100 System.out.println("in the " + name[e.len - 3]); 101 else if (e.position(ppPoint).equals("out")) 102 System.out.println("outof the " + name[e.len - 3]); 103 else 104 System.out.println("on the " + name[e.len - 3]); 105 } 106 107 } else if (shuling != -1) { 108 System.out.println("wrong number of points"); 109 } 110 break; 111 } 112 default: 113 System.out.println("Wrong Format"); 114 break; 115 } 116 } 117 } 118 119 class Point { 120 double x, y; 121 122 Point(String x1, String y1) { 123 x = Double.valueOf(x1); 124 y = Double.valueOf(y1); 125 } 126 127 double getdistan(Point p) { 128 double t = Math.sqrt(Math.pow(x - p.x, 2) + Math.pow(y - p.y, 2)); 129 return t; 130 } 131 132 static Boolean judge(String str) { 133 if (!str.matches("^[+-]?(0|(0\\.[\\d]+)?|[1-9][0-9]*(\\.[\\d]+)?)$")) { 134 return false; 135 } else 136 return true; 137 138 } 139 140 static int getp(String str, Point[] p, int sizE) 141 142 { 143 int count = 0; 144 int m = 0; 145 String[] A = str.split(" "); 146 for (String B : A) { 147 int i = 0; 148 String[] C = B.split(","); 149 if (C.length != 2) { 150 System.out.println("Wrong Format"); 151 return -1; 152 } 153 String[] num = B.split(","); 154 for (String D : C) { 155 156 if (!Point.judge(C[i])) { 157 System.out.println("Wrong Format"); 158 return -1; 159 } 160 num[i] = D; 161 i++; 162 } 163 if (m < sizE && i == 2) { 164 p[m] = new Point(num[0], num[1]); 165 m++; 166 } 167 168 count++; 169 } 170 if (count == sizE) 171 return 1; 172 else 173 return count; 174 175 } 176 177 static boolean judgeeq(Point p1, Point p2) { 178 if (p1.x == p2.x && p1.y == p2.y) 179 return true; 180 else 181 return false; 182 } 183 184 static boolean judgeeq2(Point p1, Point p2, Point p3) { 185 if (Point.judgeeq(p1, p2) && Point.judgeeq(p1, p3)) 186 return true; 187 else 188 return false; 189 } 190 191 // 去掉重复点 192 static Point[] remove_eq(Point[] p) { 193 int f = 0; 194 for (int i = 1; i < p.length - f; i++) { 195 for (int j = 0; j < i; j++) { 196 if (Point.judgeeq(p[i], p[j])) { 197 for (int k = i; k < p.length - f - 1; k++) { 198 p[k] = p[k + 1]; 199 } 200 f++; 201 } 202 } 203 } 204 Point[] p1 = new Point[p.length - f]; 205 for (int i = 0; i < p1.length; i++) 206 p1[i] = p[i]; 207 return p1; 208 } 209 210 // 去掉某位置的点 211 static Point[] remove_position(Point[] p, int i) { 212 for (int j = i; j < p.length - 1; j++) { 213 p[j] = p[j + 1]; 214 } 215 Point[] p1 = new Point[p.length - 1]; 216 for (int j = 0; j < p1.length; j++) 217 p1[j] = p[j]; 218 return p1; 219 } 220 221 // 求点集的重心 222 static Point zhongxing(Point[] p) { 223 double x = 0, y = 0; 224 for (int i = 0; i < p.length; i++) { 225 x = x + p[i].x; 226 y = y + p[i].y; 227 } 228 x = x / p.length; 229 y = y / p.length; 230 String x1 = "".valueOf(x); 231 String y1 = "".valueOf(y); 232 Point ppPoint = new Point(x1, y1); 233 return ppPoint; 234 } 235 236 // 打印点信息 237 public void print() { 238 String x = String.format("%.6f", this.x); 239 String y = String.format("%.6f", this.y); 240 x = x.replaceAll("0+?$", ""); 241 y = y.replaceAll("0+?$", ""); 242 System.out.printf("(%s , %s)\n", this.x, this.y); 243 } 244 245 } 246 247 class line { 248 Point p1; 249 Point p2; 250 double k; 251 double length; 252 253 line(Point a, Point b) { 254 p1 = a; 255 p2 = b; 256 if (p1.x != p2.x) 257 k = (p2.y - p1.y) / (p2.x - p1.x); 258 length = a.getdistan(b); 259 } 260 261 boolean xielv() { 262 263 if (p1.x == p2.x) 264 return false; 265 else 266 return true; 267 } 268 269 static boolean judgepinxing(line a, line b) { 270 if (!a.xielv() && !b.xielv()) 271 return true; 272 else if (a.xielv() && b.xielv()) { 273 if (a.k == b.k) 274 return true; 275 else 276 return false; 277 } else 278 return false; 279 280 } 281 282 // 判断三点共线 283 static boolean judgegonxian(Point[] p) { 284 if (!Point.judgeeq(p[0], p[1]) && !Point.judgeeq(p[2], p[1]) && !Point.judgeeq(p[0], p[2])) { 285 line p1 = new line(p[0], p[1]); 286 line p2 = new line(p[1], p[2]); 287 if (p1.xielv() && p2.xielv()) { 288 if (p1.k == p2.k) { 289 return true; 290 } else 291 return false; 292 } else if ((p1.xielv() && !p2.xielv()) || (!p1.xielv() && p2.xielv())) 293 return false; 294 else if (p[0].x == p[1].x && p[1].x == p[2].x) { 295 return true; 296 } else { 297 return false; 298 } 299 } else 300 301 { 302 return true; 303 } 304 305 } 306 307 // 判断四点共线 308 static boolean judgegonxian1(Point p1, Point p2, Point p3, Point p4) { 309 Point[] p = new Point[3]; 310 p[0] = p1; 311 p[1] = p2; 312 p[2] = p3; 313 if (line.judgegonxian(p)) { 314 line l = new line(p1, p3); 315 if (p1.equals(p3)) 316 l.p2 = p2; 317 if (l.judgein_line(p4)) 318 return true; 319 else 320 return false; 321 } else 322 return false; 323 324 } 325 // 点在线段内(前提:点在线上) 326 327 static boolean judgein_xianduan(line a, Point p) { 328 double max1, min1; 329 if (a.p1.x > a.p2.x) { 330 max1 = a.p1.x; 331 min1 = a.p2.x; 332 } else { 333 max1 = a.p2.x; 334 min1 = a.p1.x; 335 } 336 337 double max2, min2; 338 if (a.p1.y > a.p2.y) { 339 max2 = a.p1.y; 340 min2 = a.p2.y; 341 } else { 342 max2 = a.p2.y; 343 min2 = a.p1.y; 344 } 345 if ((p.x < max1 && p.x > min1) || Math.abs(p.x - max1) < 0.000001 || Math.abs(p.x - min1) < 0.000001) { 346 if ((p.y < max2 && p.y > min2) || Math.abs(p.y - max2) < 0.000001 || Math.abs(p.y - min2) < 0.000001) 347 return true; 348 else 349 return false; 350 } else 351 return false; 352 } 353 354 static boolean jiaodian(line a, line b, Point[] jd, int count) { 355 double x = 0, y = 0, A1, B1, C1, A2, B2, C2; 356 if (line.judgepinxing(a, b)) 357 return false; 358 if (a.xielv() && b.xielv()) { 359 360 A1 = a.p1.y - a.p2.y; 361 B1 = a.p2.x - a.p1.x; 362 C1 = (a.p2.y - a.p1.y) * a.p1.x - (a.p2.x - a.p1.x) * a.p1.y; 363 A2 = b.p1.y - b.p2.y; 364 B2 = b.p2.x - b.p1.x; 365 C2 = (b.p2.y - b.p1.y) * b.p1.x - (b.p2.x - b.p1.x) * b.p1.y; 366 x = (B1 * C2 - B2 * C1) / (A1 * B2 - A2 * B1); 367 y = (A1 * C2 - A2 * C1) / (B1 * A2 - B2 * A1); 368 369 } else if (a.xielv() && !b.xielv()) { 370 x = b.p1.x; 371 y = a.p1.y + ((b.p1.x - a.p1.x) * (a.p2.y - a.p1.y) / (a.p2.x - a.p1.x)); 372 373 } else if (!a.xielv() && b.xielv()) { 374 x = a.p1.x; 375 y = b.p1.y + ((a.p1.x - b.p1.x) * (b.p2.y - b.p1.y) / (b.p2.x - b.p1.x)); 376 377 } 378 String x1 = "".valueOf(x); 379 String y1 = "".valueOf(y); 380 jd[count] = new Point(x1, y1); 381 if (line.judgein_xianduan(a, jd[count]) && line.judgein_xianduan(b, jd[count])) 382 return true; 383 else 384 return false; 385 386 } 387 388 static boolean judgechonghe(line a, line b) { 389 if (line.judgepinxing(a, b) && a.judgein_line(b.p1)) 390 return true; 391 else 392 return false; 393 394 } 395 396 // 判断点在线上 397 boolean judgein_line(Point p) { 398 double A, B, C; 399 A = p1.y - p2.y; 400 B = p2.x - p1.x; 401 C = (p2.y - p1.y) * p1.x - (p2.x - p1.x) * p1.y; 402 if ((A * p.x + B * p.y + C) == 0) 403 return true; 404 else { 405 return false; 406 } 407 } 408 409 // 判断两条线段有无交点 410 static boolean have_jiaodian(line a, line b) { 411 Point[] jd = new Point[2]; 412 if (line.jiaodian(a, b, jd, 0) && line.jiaodian(b, a, jd, 1)) 413 return true; 414 else 415 return false; 416 417 } 418 419 // 求向量叉积 420 double vectorCrossMul(line a) { 421 double x = 0; 422 x = (p2.x - p1.x) * (a.p2.y - a.p1.y) - (a.p2.x - a.p1.x) * (p2.y - p1.y); 423 return x; 424 } 425 426 // 求两直线夹角 427 double vectorangle(line a) { 428 double x = 0.0; 429 x = (p2.x - p1.x) * (a.p2.x - a.p1.x) + (p2.y - p1.y) * (a.p2.y - a.p1.y); 430 double y = 0.0; 431 y = length * a.length; 432 return Math.acos(x / y); 433 } 434 435 // 打印线信息 436 public void print() { 437 System.out.println(p1.x + "," + p1.y + " " + p2.x + "," + p2.y); 438 } 439 440 } 441 442 //多边形类 443 class graphical { 444 int len = 0; 445 Point[] points; 446 line[] lines; 447 double zhouchang = 0, area = 0; 448 boolean can_graphical = true; 449 450 graphical(Point[] p) { 451 // Point[] p1=new Point[p.length]; 452 // 去掉重复点 453 // points = new Point[p.length]; 454 points = Point.remove_eq(p); 455 if (points.length <= 2) { 456 can_graphical = false; 457 return; 458 } 459 // 去除中间点 460 int f = 0; 461 for (int i = 0; i < points.length - f; i++) { 462 463 int first = i, second = (i + 1) % points.length, third = (i + 2) % points.length; 464 Point[] p2 = new Point[3]; 465 p2[0] = points[first]; 466 p2[1] = points[second]; 467 p2[2] = points[third]; 468 line l = new line(p2[0], p2[2]); 469 if (line.judgegonxian(p2) && line.judgein_xianduan(l, p2[1])) { 470 f++; 471 this.points = Point.remove_position(points, second); 472 i = -1; 473 } else if (!line.judgegonxian(p2)) { 474 475 } else { 476 can_graphical = false; 477 return; 478 } 479 } 480 481 this.len = points.length; 482 // 初始化边 483 this.lines = new line[this.len]; 484 for (int i = 0; i < this.len; i++) { 485 int first = i, second = (i + 1) % this.len; 486 this.lines[i] = new line(this.points[first], this.points[second]); 487 } 488 489 // 判断任意不相邻边是否有交点 490 cheak_can(); 491 492 area = graphical.area(this); 493 zhouchang = graphical.zhouchang(this); 494 495 } 496 497 // 判断两个图形完全分离 498 static boolean isseparate(graphical e1, graphical e2) { 499 int count1 = 0; 500 int count2 = 0; 501 for (int i = 0; i < e1.len; i++) { 502 if (!e2.position(e1.points[i]).equals("out")) { 503 count1++; 504 } 505 } 506 for (int i = 0; i < e2.len; i++) { 507 if (!e1.position(e2.points[i]).equals("out")) { 508 count2++; 509 } 510 } 511 // double x = graphical.overlap_area(e1, e2); 512 if (count1 == 0 && count2 == 0) 513 return true; 514 else 515 return false; 516 } 517 518 // 判断两个图形是否连接 519 520 // e1包含e2 521 static boolean iscontaingra(graphical e1, graphical e2) { 522 for (int i = 0; i < e2.len; i++) { 523 if (!e1.position(e2.points[i]).equals("in") && !e1.position(e2.points[i]).equals("on")) { 524 return false; 525 } 526 527 } 528 return true; 529 } 530 531 // 判断两个图形是否完全一样 532 static boolean issame(graphical e1, graphical e2) { 533 int[] falg = new int[e1.len]; 534 Point[] px = new Point[e2.len]; 535 int px_len = e2.len; 536 for (int i = 0; i < e2.len; i++) 537 px[i] = e2.points[i]; 538 if (e1.len == e2.len) { 539 for (int i = 0; i < e1.len; i++) { 540 for (int j = 0; j < px_len; j++) 541 if (Point.judgeeq(e1.points[i], px[j])) { 542 falg[i] = 1; 543 px = Point.remove_position(px, j); 544 px_len--; 545 } 546 } 547 for (int i = 0; i < e1.len; i++) 548 if (falg[i] == 0) 549 return false; 550 return true; 551 } else 552 return false; 553 } 554 555 // 求出两个图形的重叠面积 556 static double overlap_area(graphical e1, graphical e2) { 557 Point[] pp = new Point[200]; 558 int p_len = 0; 559 // 线与线的交点 560 for (int i = 0; i < e1.len; i++) { 561 for (int j = 0; j < e2.len; j++) { 562 if (line.jiaodian(e1.lines[i], e2.lines[j], pp, p_len)) 563 p_len++; 564 } 565 } 566 // 内部的顶点 567 for (int i = 0; i < e1.len; i++) { 568 if (!e2.position(e1.points[i]).equals("out")) { 569 pp[p_len++] = e1.points[i]; 570 } 571 } 572 for (int i = 0; i < e2.len; i++) { 573 if (!e1.position(e2.points[i]).equals("out")) { 574 pp[p_len++] = e2.points[i]; 575 } 576 } 577 Point[] p = new Point[p_len]; 578 for (int i = 0; i < p_len; i++) 579 p[i] = pp[i]; 580 581 // 根据逆时针角度大小为坐标数组排序 582 p = Point.remove_eq(p); 583 String x1 = "".valueOf(p[0].x); 584 String y1 = "".valueOf(p[0].y); 585 Point p0 = new Point(x1, y1); 586 Point px = Point.zhongxing(p); 587 588 /* 589 * Arrays.sort()排序 默认情况下从小到大 用Comparator进行排序//定义是用泛型 Comparator<int>报错,用integer 590 * Comparator接口中,包含一个最核心的方法int compare() 该方法用于定义排序规则 591 * compare的参数o1,o2也是泛型T(排序类型不是基本类型) compare的返回值为>0,则o1>o2 592 * 593 */ 594 595 Arrays.sort(p, 1, p.length, new Comparator<Point>() { 596 @Override 597 public int compare(Point o1, Point o2) { 598 line l0 = new line(px, p0); 599 line l1 = new line(px, o1); 600 line l2 = new line(px, o2); 601 // 求两条线的夹角 602 double angle1 = l0.vectorangle(l1); 603 double angle2 = l0.vectorangle(l2); 604 if (l0.vectorCrossMul(l1) < 0) 605 angle1 = 2 * Math.PI - angle1; 606 if (l0.vectorCrossMul(l2) < 0) 607 angle2 = 2 * Math.PI - angle2; 608 // angle1>angle2 609 if (angle1 - angle2 > 0.000001) 610 return 1; 611 // angle1=angle2 612 if (Math.abs(angle1 - angle2) < 0.000001) 613 return 0; 614 // angle1<angle2 615 return -1; 616 } 617 }); 618 619 graphical e = new graphical(p); 620 return e.area; 621 622 } 623 624 // 判断点在多边形的位置(面积法) 625 String position(Point p) { 626 String s = ""; 627 int falg = 0; 628 double x = 0; 629 for (int i = 0; i < this.len; i++) { 630 x += triangle.area(p, this.points[i], this.points[(i + 1) % this.len]); 631 } 632 if (Math.abs(x - this.area) < 0.000001) { 633 for (int i = 0; i < this.len; i++) { 634 if (lines[i].judgein_line(p) && line.judgein_xianduan(lines[i], p)) { 635 falg = 1; 636 break; 637 } 638 } 639 if (falg == 1) 640 s = "on"; 641 else 642 s = "in"; 643 } else 644 s = "out"; 645 return s; 646 } 647 648 // 判断不相邻的边是否有交点 649 void cheak_can() { 650 for (int i = 0; i < len; i++) { 651 for (int j = i + 2; j < len; j++) { 652 if (i == 0 && j == len - 1) 653 continue; 654 if (line.have_jiaodian(lines[i], lines[j])) { 655 can_graphical = false; 656 return; 657 } 658 } 659 } 660 } 661 662 // 多边形面积 663 static double area(graphical e) { 664 double x = 0; 665 Point oPoint = new Point("0", "0"); 666 for (int i = 0; i < e.len; i++) { 667 line l1 = new line(oPoint, e.points[i]); 668 line l2 = new line(oPoint, e.points[(i + 1) % e.len]); 669 x = x + 0.5 * l1.vectorCrossMul(l2); 670 } 671 x = Math.abs(x); 672 return x; 673 } 674 675 // 多边形周长 676 static double zhouchang(graphical e) { 677 double x = 0; 678 for (int i = 0; i < e.len; i++) { 679 x = x + e.points[i].getdistan(e.points[(i + 1) % e.len]); 680 } 681 return x; 682 } 683 684 // 打印多边形信息 685 void print() { 686 if (!this.can_graphical) { 687 System.out.println("not a graphical"); 688 return; 689 } 690 System.out.println("点数为:" + this.len); 691 for (int i = 0; i < this.len; i++) { 692 this.points[i].print(); 693 } 694 for (int i = 0; i < this.len; i++) { 695 this.lines[i].print(); 696 } 697 System.out.println("周长为:" + this.zhouchang); 698 System.out.println("面积为:" + this.area); 699 } 700 701 } 702 703 class triangle extends graphical { 704 705 triangle(Point[] p) { 706 super(p); 707 if (!this.can_graphical && this.len != 3) 708 System.out.println("not a triangle"); 709 } 710 711 static double area(Point a, Point b, Point c) { 712 double x1 = a.getdistan(b); 713 double x2 = b.getdistan(c); 714 double x3 = c.getdistan(a); 715 double p = (x1 + x2 + x3) / 2; 716 return Math.sqrt(p * (p - x1) * (p - x2) * (p - x3)); 717 } 718 } 719 720 class quadrilateral extends graphical { 721 722 quadrilateral(Point[] p) { 723 super(p); 724 if (!this.can_graphical && this.len != 4) 725 System.out.println("not a quadrilateral"); 726 } 727 728 } 729 730 class pentagon extends graphical { 731 732 pentagon(Point[] p) { 733 super(p); 734 if (!this.can_graphical && this.len != 5) 735 System.out.println("not a pentagon"); 736 } 737 738 }
期中考试
(1)题目1
7-1 点与线(类设计)
设计一个类表示平面直角坐标系上的点Point,私有属性分别为横坐标x与纵坐标y,数据类型均为实型数,除构造方法以及属性的getter与setter方法外,定义一个用于显示信息的方法display(),用来输出该
坐标点的坐标信息,格式如下:(x,y),数值保留两位小数。为简化题目,其中,坐标点的取值范围设定为(0,200]。若输入有误,系统则直接输出Wrong Format。 设计一个类表示平面直角坐标系上的线Line,私有属性除了标识线段两端的点point1、point2外,还有一个字符串类型的color,用于表示该线段的颜色,同样,除构造方法以及属性的getter与setter方法
外,定义一个用于计算该线段长度的方法getDistance(),还有一个用于显示信息的方法display(),用来输出线段的相关信息,输出格式如下:
``` The line's color is:颜色值 The line's begin point's Coordinate is: (x1,y1) The line's end point's Coordinate is: (x2,y2) The line's length is:长度值 ``` 其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)方法。
设计类图如下图所示:
** 题目要求:在主方法中定义一条线段对象,从键盘输入该线段的起点坐标与终点坐标以及颜色,然后调用该线段的display()方法进行输出。**
以下情况为无效作业
无法运行
设计不符合所给类图要求
未通过任何测试点测试
判定为抄袭
输入格式:
分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。
输出格式:
The line's color is:颜色值 The line's begin point's Coordinate is: (x1,y1) The line's end point's Coordinate is: (x2,y2) The line's length is:长度值
输入样例:
5
9.4
12.3
84
Red
输出样例:
The line's color is:Red The line's begin point's Coordinate is: (5.00,9.40) The line's end point's Coordinate is: (12.30,84.00) The line's length is:74.96
-
设计与分析
这题很简单,而且类图也给出来了。
圈复杂度分析图:
-
踩坑心得
就注意私有属性需要调用方法访问。
-
改进建议
无。
-
源码附录

1 import java.util.Scanner; 2 public class Main{ 3 4 public static void main(String[] args) { 5 Scanner in = new Scanner(System.in); 6 double x1 = in.nextDouble(); 7 double y1 = in.nextDouble(); 8 double x2 = in.nextDouble(); 9 double y2 = in.nextDouble(); 10 Apoint p1 = new Apoint(x1, y1); 11 Apoint p2 = new Apoint(x2, y2); 12 String color = in.next(); 13 if (x1 <= 0 || x1 > 200 || x2 <= 0 || x2 > 200 || y1 <= 0 || y1 > 200 || y2 <= 0 || y2 > 200) { 14 System.out.print("Wrong Format");return; 15 } 16 Aline l = new Aline(p1, p2, color); 17 l.display(); 18 } 19 20 } 21 22 class Apoint { 23 private double x; 24 private double y; 25 26 public Apoint() { 27 28 } 29 30 public Apoint(double x, double y) { 31 super(); 32 this.x = x; 33 this.y = y; 34 } 35 36 public double getX() { 37 return x; 38 } 39 40 public void setX(double x) { 41 this.x = x; 42 } 43 44 public double getY() { 45 return y; 46 } 47 48 public void setY(double y) { 49 this.y = y; 50 } 51 52 public void display() { 53 System.out.printf("(%.2f,%.2f)\n", getX(), getY()); 54 } 55 56 } 57 58 class Aline { 59 private Apoint pStart; 60 private Apoint pend; 61 private String color; 62 63 public Aline() { 64 65 } 66 67 public Aline(Apoint pStart, Apoint pend, String color) { 68 super(); 69 this.pStart = pStart; 70 this.pend = pend; 71 this.color = color; 72 } 73 74 public Apoint getpStart() { 75 return pStart; 76 } 77 78 public void setpStart(Apoint pStart) { 79 this.pStart = pStart; 80 } 81 82 public Apoint getPend() { 83 return pend; 84 } 85 86 public void setPend(Apoint pend) { 87 this.pend = pend; 88 } 89 90 public String getColor() { 91 return color; 92 } 93 94 public void setColor(String color) { 95 this.color = color; 96 } 97 98 public double getDistance() { 99 return Math.sqrt(Math.pow(pStart.getX() - pend.getX(), 2) + Math.pow(pStart.getY() - pend.getY(), 2)); 100 } 101 102 public void display() { 103 System.out.println("The line's color is:" + getColor()); 104 System.out.println("The line's begin point's Coordinate is:"); 105 System.out.printf("(%.2f,%.2f)\n", pStart.getX(), pStart.getY()); 106 System.out.println("The line's end point's Coordinate is:"); 107 System.out.printf("(%.2f,%.2f)\n", pend.getX(), pend.getY()); 108 System.out.printf("The line's length is:%.2f", getDistance()); 109 } 110 111 }
(2)题目2
7-2 点线面问题重构(继承与多态)
在“点与线(类设计)”题目基础上,对题目的类设计进行重构,以实现继承与多态的技术性需求。 对题目中的点Point类和线Line类进行进一步抽象,定义一个两个类的共同父类Element(抽象类),将display()方法在该方法中进行声明(抽象方法),将Point类和Line类作为该类的子类。 再定义一个Element类的子类面Plane,该类只有一个私有属性颜色color,除了构造方法和属性的getter、setter方法外,display()方法用于输出面的颜色,
输出格式如下:The Plane's color is:颜色 在主方法内,定义两个Point(线段的起点和终点)对象、一个Line对象和一个Plane对象,依次从键盘输入两个Point对象的起点、终点坐标和颜色值(Line对象和Plane对象颜色相同),
然后定义一个Element类的引用,分别使用该引用调用以上四个对象的display()方法,从而实现多态特性。示例代码如下: element = p1;//起点Point element.display(); element = p2;//终点Point element.display(); element = line;//线段 element.display(); element = plane;//面 element.display();
类结构如下图所示:
其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)方法。
以下情况为无效作业
无法运行
设计不符合所给类图要求
未通过任何测试点测试
判定为抄袭
输入格式:
分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。
输入格式:
分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。
输出格式:
(x1,y1) (x2,y2) The line's color is:颜色值 The line's begin point's Coordinate is: (x1,y1) The line's end point's Coordinate is: (x2,y2) The line's length is:长度值 The Plane's color is:颜色值
输入样例:
5
9.4
12.3
84
Red
输出样例:
(5.00,9.40) (12.30,84.00) The line's color is:Red The line's begin point's Coordinate is: (5.00,9.40) The line's end point's Coordinate is: (12.30,84.00) The line's length is:74.96 The Plane's color is:Red
-
设计与分析
这题也很简单,给出圈复杂度分析图。
圈复杂度分析图:
-
踩坑心得
注意父类中的方法是抽象方法,在子类中实现。
-
改进建议
无。
-
源码附录

1 import java.util.Scanner; 2 public class Main { 3 4 public static void main(String[] args) { 5 Scanner in = new Scanner(System.in); 6 double x1 = in.nextDouble(); 7 double y1 = in.nextDouble(); 8 double x2 = in.nextDouble(); 9 double y2 = in.nextDouble(); 10 Apoint p1 = new Apoint(x1, y1); 11 Apoint p2 = new Apoint(x2, y2); 12 String color = in.next(); 13 /*判断格式错误,直接输出Wrong Format*/ 14 if (x1 <= 0 || x1 > 200 || x2 <= 0 || x2 > 200 || y1 <= 0 || y1 > 200 || y2 <= 0 || y2 > 200) { 15 System.out.print("Wrong Format");return; 16 } 17 Aline l = new Aline(p1, p2, color); 18 Plane p = new Plane(color); 19 /*多态*/ 20 Element element; 21 element = p1; 22 element.display(); 23 element = p2; 24 element.display(); 25 element = l; 26 element.display(); 27 element = p; 28 element.display(); 29 } 30 31 } 32 33 class Apoint extends Element { 34 private double x; 35 private double y; 36 37 public Apoint() { 38 39 } 40 41 public Apoint(double x, double y) { 42 super(); 43 this.x = x; 44 this.y = y; 45 } 46 47 public double getX() { 48 return x; 49 } 50 51 public void setX(double x) { 52 this.x = x; 53 } 54 55 public double getY() { 56 return y; 57 } 58 59 public void setY(double y) { 60 this.y = y; 61 } 62 63 public void display() { 64 System.out.printf("(%.2f,%.2f)\n", getX(), getY()); 65 } 66 67 } 68 69 class Aline extends Element { 70 private Apoint pStart; 71 private Apoint pend; 72 private String color; 73 74 public Aline() { 75 76 } 77 78 public Aline(Apoint pStart, Apoint pend, String color) { 79 super(); 80 this.pStart = pStart; 81 this.pend = pend; 82 this.color = color; 83 } 84 85 public Apoint getpStart() { 86 return pStart; 87 } 88 89 public void setpStart(Apoint pStart) { 90 this.pStart = pStart; 91 } 92 93 public Apoint getPend() { 94 return pend; 95 } 96 97 public void setPend(Apoint pend) { 98 this.pend = pend; 99 } 100 101 public String getColor() { 102 return color; 103 } 104 105 public void setColor(String color) { 106 this.color = color; 107 } 108 109 public double getDistance() { 110 return Math.sqrt(Math.pow(pStart.getX() - pend.getX(), 2) + Math.pow(pStart.getY() - pend.getY(), 2)); 111 } 112 113 public void display() { 114 System.out.println("The line's color is:" + getColor()); 115 System.out.println("The line's begin point's Coordinate is:"); 116 System.out.printf("(%.2f,%.2f)\n", pStart.getX(), pStart.getY()); 117 System.out.println("The line's end point's Coordinate is:"); 118 System.out.printf("(%.2f,%.2f)\n", pend.getX(), pend.getY()); 119 System.out.printf("The line's length is:%.2f\n", getDistance()); 120 } 121 122 } 123 124 class Plane extends Element { 125 private String color; 126 127 public Plane() { 128 super(); 129 // TODO Auto-generated constructor stub 130 } 131 132 public Plane(String color) { 133 super(); 134 this.color = color; 135 } 136 137 public String getColor() { 138 return color; 139 } 140 141 public void setColor(String color) { 142 this.color = color; 143 } 144 145 @Override 146 public void display() { 147 System.out.println("The Plane's color is:" + getColor()); 148 } 149 150 } 151 152 abstract class Element { 153 /*抽象方法声明,在子类中实现(方法覆盖)*/ 154 public abstract void display(); 155 }
(3)题目3
7-3 点线面问题再重构(容器类)
在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。 在原有类设计的基础上,增加一个GeometryObject容器类,其属性为ArrayList<Element>类型的对象(若不了解泛型,可以不使用<Element>) 增加该类的add()方法及remove(int index)方法,其功能分别为向容器中增加对象及删除第index - 1(ArrayList中index>=0)个对象 在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下: 1:向容器中增加Point对象 2:向容器中增加Line对象 3:向容器中增加Plane对象 4:删除容器中第index - 1个数据,若index数据非法,则无视此操作 0:输入结束
输入结束后,按容器中的对象顺序分别调用每个对象的display()
方法进行输出。
示例代码如下:
choice = input.nextInt(); while(choice != 0) { switch(choice) { case 1://insert Point object into list ... break; case 2://insert Line object into list ... break; case 3://insert Plane object into list ... break; case 4://delete index - 1 object from list int index = input.nextInt(); ... } choice = input.nextInt(); }
类图如下:
输入格式:
switch(choice) { case 1://insert Point object into list 输入“点”对象的x,y值 break; case 2://insert Line object into list 输入“线”对象两个端点的x,y值 break; case 3://insert Plane object into list 输入“面”对象的颜色值 break; case 4://delete index - 1 object from list 输入要删除的对象位置(从1开始) ... }
输出格式:
Point、Line、Plane的输出参考题目2
删除对象时,若输入的index超出合法范围,程序自动忽略该操作
输入样例:
1 3.4 5.6 2 4.4 8.0 0.98 23.888 Red 3 Black 1 9.8 7.5 3 Green 4 3 0
输出样例:
(3.40,5.60) The line's color is:Red The line's begin point's Coordinate is: (4.40,8.00) The line's end point's Coordinate is: (0.98,23.89) The line's length is:16.25 (9.80,7.50) The Plane's color is:Green
-
设计与分析
简单,直接给出圈复杂度分析图。
圈复杂度分析图:
-
踩坑心得
坑点1:当输入的index非法时,忽略操作。
-
改进建议
无。
-
源码附录

1 import java.util.ArrayList; 2 import java.util.Scanner; 3 public class Main{ 4 5 public static void main(String[] args) { 6 GeometryObject geometryObject = new GeometryObject(); 7 Scanner in = new Scanner(System.in); 8 int choice = in.nextInt(); 9 while (choice != 0) { 10 switch (choice) { 11 case 1://insert Point object into list 12 double x = in.nextDouble(); 13 double y = in.nextDouble(); 14 geometryObject.add(new Apoint(x, y)); 15 break; 16 case 2://insert Line object into list 17 double x1 = in.nextDouble(); 18 double y1 = in.nextDouble(); 19 double x2 = in.nextDouble(); 20 double y2 = in.nextDouble(); 21 String color = in.next(); 22 geometryObject.add(new Aline(new Apoint(x1, y1), new Apoint(x2, y2), color)); 23 break; 24 case 3://insert Plane object into list 25 String color1 = in.next(); 26 geometryObject.add(new Plane(color1)); 27 break; 28 case 4://delete index - 1 object from list 29 int index = in.nextInt(); 30 geometryObject.remove(index); 31 break; 32 } 33 choice = in.nextInt(); 34 } 35 for (int i = 0; i < geometryObject.getList().size(); i++) { 36 geometryObject.getList().get(i).display(); 37 } 38 in.close(); 39 } 40 } 41 42 class Apoint extends Element { 43 private double x; 44 private double y; 45 46 public Apoint() { 47 48 } 49 50 public Apoint(double x, double y) { 51 super(); 52 this.x = x; 53 this.y = y; 54 } 55 56 public double getX() { 57 return x; 58 } 59 60 public void setX(double x) { 61 this.x = x; 62 } 63 64 public double getY() { 65 return y; 66 } 67 68 public void setY(double y) { 69 this.y = y; 70 } 71 72 public void display() { 73 System.out.printf("(%.2f,%.2f)\n", getX(), getY()); 74 } 75 76 } 77 78 class Aline extends Element { 79 private Apoint pStart; 80 private Apoint pend; 81 private String color; 82 83 public Aline() { 84 85 } 86 87 public Aline(Apoint pStart, Apoint pend, String color) { 88 super(); 89 this.pStart = pStart; 90 this.pend = pend; 91 this.color = color; 92 } 93 94 public Apoint getpStart() { 95 return pStart; 96 } 97 98 public void setpStart(Apoint pStart) { 99 this.pStart = pStart; 100 } 101 102 public Apoint getPend() { 103 return pend; 104 } 105 106 public void setPend(Apoint pend) { 107 this.pend = pend; 108 } 109 110 public String getColor() { 111 return color; 112 } 113 114 public void setColor(String color) { 115 this.color = color; 116 } 117 118 public double getDistance() { 119 return Math.sqrt(Math.pow(pStart.getX() - pend.getX(), 2) + Math.pow(pStart.getY() - pend.getY(), 2)); 120 } 121 122 public void display() { 123 System.out.println("The line's color is:" + getColor()); 124 System.out.println("The line's begin point's Coordinate is:"); 125 System.out.printf("(%.2f,%.2f)\n", pStart.getX(), pStart.getY()); 126 System.out.println("The line's end point's Coordinate is:"); 127 System.out.printf("(%.2f,%.2f)\n", pend.getX(), pend.getY()); 128 System.out.printf("The line's length is:%.2f\n", getDistance()); 129 } 130 131 } 132 133 class Plane extends Element { 134 private String color; 135 136 public Plane() { 137 super(); 138 // TODO Auto-generated constructor stub 139 } 140 141 public Plane(String color) { 142 super(); 143 this.color = color; 144 } 145 146 public String getColor() { 147 return color; 148 } 149 150 public void setColor(String color) { 151 this.color = color; 152 } 153 154 @Override 155 public void display() { 156 System.out.println("The Plane's color is:" + getColor()); 157 } 158 159 } 160 161 abstract class Element { 162 public abstract void display(); 163 } 164 165 class GeometryObject { 166 private ArrayList<Element> list = new ArrayList<Element>(); 167 168 public GeometryObject() { 169 170 } 171 172 public void add(Element element) { 173 list.add(element); 174 } 175 176 public void remove(int index) { 177 if (list.size() > index - 1 && index > 0) 178 list.remove(index - 1); 179 else 180 return; 181 } 182 183 public ArrayList<Element> getList() { 184 return list; 185 } 186 }
总结:
这次的三次作业让我对与面向对象编程中的封装、继承、多态有了更深刻的认识。在五边形的大作业中,让我认识到了继承的重要性,如果不是提取生成了父类,我想那次大作业我应该就写不出满分的代码了。封装最主要的功能在于我们能修改自己的实现代码,而不用修改哪些调用我们代码的程序片断。继承提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】