一、前言
1.pta题目集4(凸四边形的计算)总结
本题题目难度比第三次的难度要更大,更为复杂,总共有三道题目,涉及到了正则表达式的使用,对于字符串的处理,类的涉及,以及四边形的性质及计算。
2.pta题目集5(凸五边形的计算)总结
本题题目在前两次的题目基础上升级为五边形的计算,同时涉及了四边形以及三角形的性质及计算,题目更加复杂。
3.期中考试
本次题目相对来说还是比较简单的,但是由于涉及到类的设计,类的继承与多态,以及容器类的使用,所以还是有一点点难度,因为学的还不够扎实。
二、设计与分析
-
pta题目集4(凸四边形的计算)设计与分析
1)7-1 sdut-String-2 识蛟龙号载人深潜,立科技报国志(II)(正则表达式)
背景简介:
“蛟龙号”载人深潜器是我国首台自主设计、自主集成研制的作业型深海载人潜水器,设计最大下潜深度为7000米级,也是目前世界上下潜能力最强的作业型载人潜水器。“蛟龙号”可在占世界海洋面积99.8%的广阔海域中使用,对于我国开发利用深海的资源有着重要的意义。
中国是继美、法、俄、日之后世界上第五个掌握大深度载人深潜技术的国家。在全球载人潜水器中,“蛟龙号”属于第一梯队。目前全世界投入使用的各类载人潜水器约90艘,其中下潜深度超过1000米的仅有12艘,更深的潜水器数量更少,目前拥有6000米以上深度载人潜水器的国家包括中国、美国、日本、法国和俄罗斯。除中国外,其他4国的作业型载人潜水器最大工作深度为日本深潜器的6527米,因此“蛟龙号”载人潜水器在西太平洋的马里亚纳海沟海试成功到达7020米海底,创造了作业类载人潜水器新的世界纪录。
从2009年至2012年,蛟龙号接连取得1000米级、3000米级、5000米级和7000米级海试成功。下潜至7000米,说明蛟龙号载人潜水器集成技术的成熟,标志着我国深海潜水器成为海洋科学考察的前沿与制高点之一。
2012年6月27日11时47分,中国“蛟龙”再次刷新“中国深度”——下潜7062米。6月3日,“蛟龙”出征以来,已经连续书写了5个“中国深度”新纪录:6月15日,6671米;6月19日,6965米;6月22日,6963米;6月24日,7020米;6月27日,7062米。下潜至7000米,标志着我国具备了载人到达全球99%以上海洋深处进行作业的能力,标志着“蛟龙”载人潜水器集成技术的成熟,标志着我国深海潜水器成为海洋科学考察的前沿与制高点之一,标志着中国海底载人科学研究和资源勘探能力达到国际领先水平。
‘蛟龙’号是我国载人深潜发展历程中的一个重要里程碑。它不只是一个深海装备,更代表了一种精神,一种不畏艰险、赶超世界的精神,它是中华民族进军深海的号角。
了解蛟龙号”载人深潜器“的骄人业绩,为我国海底载人科学研究和资源勘探能力达到国际领先水平而自豪,小伙伴们与祖国同呼吸、共命运,一定要学好科学文化知识、提高个人能力,增强创新意识,做事精益求精,立科技报国之志!
请编写程序,实现如下功能:读入关于蛟龙号载人潜水器探测数据的多行字符串,从给定的信息找出数字字符,输出每行的数字之和。
提示 若输入为“2012年2月”,则该行的输出为:2014。若干个连续的数字字符作为一个整体,以十进制形式相加。
输入格式:
读入关于蛟龙号载人潜水器探测数据的多行字符串,每行字符不超过80个字符。
以"end"结束。
输出格式:
与输入行相对应的各个整数之和。
源码如下:
import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args){ Scanner s=new Scanner(System.in); String a=s.nextLine(); Pattern p=Pattern.compile("[0-9]+");//匹配数字 int sum; while(!a.equals("end")) { Matcher m=p.matcher(a); sum=0; while(m.find()) { sum+=Integer.valueOf(m.group()); } System.out.println(sum); a=s.nextLine(); } } }View Code
圈复杂度图如下:
心得:本题的主要考点是正则表达式的使用,通过正则表达式搜索文中的数字,然后转换为int类型进行计算。
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"。
源码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner s = new Scanner(System.in); String a = s.nextLine(); char n = a.charAt(0); if (n < '1' || n > '5') { System.out.println("Wrong Format"); return; } if (a.charAt(1) != ':') { System.out.println("Wrong Format"); return; } int count = 0; for (int i = 2; i < a.length(); i++)//计算坐标个数 { if (a.charAt(i) == ',') count++; } String c = a.substring(2); String b[] = c.split(" ");//存坐标 for (int i = 0; i < b.length; i++) { if (!b[i].matches("^(-?\\+?(0|[1-9][0-9]*))(\\.[0-9]*)?[,](-?\\+?(0|[1-9][0-9]*))(\\.[0-9]*)?$")) { System.out.println("Wrong Format"); return; } } if ((n == '1' || n == '2' || n == '3') && count != 4) { System.out.println("wrong number of points"); return; } if ((n == '4') && count != 6) { System.out.println("wrong number of points"); return; } if ((n == '5') && count != 5) { System.out.println("wrong number of points"); return; } String d[] = null; if (b.length == 4) { d = b[0].split(","); double x1 = Double.parseDouble(d[0]); double y1 = Double.parseDouble(d[1]); d = b[1].split(","); double x2 = Double.parseDouble(d[0]); double y2 = Double.parseDouble(d[1]); d = b[2].split(","); double x3 = Double.parseDouble(d[0]); double y3 = Double.parseDouble(d[1]); d = b[3].split(","); double x4 = Double.parseDouble(d[0]); double y4 = Double.parseDouble(d[1]); if (n == '1') { Point2 point = new Point2(x1, y1, x2, y2, x3, y3,x4,y4); point.xuanxiang1(); }else if(n=='2'){ Point2 point = new Point2(x1, y1, x2, y2, x3, y3,x4,y4); point.xuanxiang2(); }else if(n=='3') { Point2 point = new Point2(x1, y1, x2, y2, x3, y3,x4,y4); point.xuanxiang3(); } } if (b.length == 5) { d = b[0].split(","); double x1 = Double.parseDouble(d[0]); double y1 = Double.parseDouble(d[1]); d = b[1].split(","); double x2 = Double.parseDouble(d[0]); double y2 = Double.parseDouble(d[1]); d = b[2].split(","); double x3 = Double.parseDouble(d[0]); double y3 = Double.parseDouble(d[1]); d = b[3].split(","); double x4 = Double.parseDouble(d[0]); double y4 = Double.parseDouble(d[1]); d = b[4].split(","); double x5 = Double.parseDouble(d[0]); double y5 = Double.parseDouble(d[1]); if(n=='5') { Point2 point = new Point2(x1, y1, x2, y2, x3, y3,x4,y4,x5,y5); point.xuanxiang5(); } } } } class Point2 { private double x1; private double y1; private double x2; private double y2; private double x3; private double y3; private double x4; private double y4; private double x5; private double y5; private double x6; private double y6; public Point2() { super(); } public Point2(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { super(); this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.x3 = x3; this.y3 = y3; this.x4 = x4; this.y4 = y4; } public Point2(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5) { super(); this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.x3 = x3; this.y3 = y3; this.x4 = x4; this.y4 = y4; this.x5 = x5; this.y5 = y5; } public Point2(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, double x6, double y6) { super(); this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.x3 = x3; this.y3 = y3; this.x4 = x4; this.y4 = y4; this.x5 = x5; this.y5 = y5; this.x6 = x6; this.y6 = y6; } public double getX1() { return x1; } public void setX1(double x1) { this.x1 = x1; } public double getY1() { return y1; } public void setY1(double y1) { this.y1 = y1; } public double getX2() { return x2; } public void setX2(double x2) { this.x2 = x2; } public double getY2() { return y2; } public void setY2(double y2) { this.y2 = y2; } public double getX3() { return x3; } public void setX3(double x3) { this.x3 = x3; } public double getY3() { return y3; } public void setY3(double y3) { this.y3 = y3; } public double getX4() { return x4; } public void setX4(double x4) { this.x4 = x4; } public double getY4() { return y4; } public void setY4(double y4) { this.y4 = y4; } public double getX5() { return x5; } public void setX5(double x5) { this.x5 = x5; } public double getY5() { return y5; } public void setY5(double y5) { this.y5 = y5; } public double getX6() { return x6; } public void setX6(double x6) { this.x6 = x6; } public double getY6() { return y6; } public void setY6(double y6) { this.y6 = y6; } public boolean chonghe(double x1, double y1, double x2, double y2)//判断两个点是否重合 { if (x1 == x2 && y1 == y2) return true; else return false; } public double slop(double x1, double y1, double x2, double y2) { double k; k = (y2 - y1) / (x2 - x1); return k; } double distance(double x1, double y1, double x2, double y2) { double d = 0; d = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); return d; } public boolean pingxing(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { double k1, k2; k1 = (y2 - y1) / (x2 - x1); k2 = (y4 - y3) / (x4 - x3); if (k1 == k2) return true; else return false; } /* 输入四个点坐标,判断是否是四边形、平行四边形 判断结果输出true/false,结果之间以一个英文空格符分隔。 */ public static boolean jiaodian1(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4) { boolean p=false; double a1=y2-y1; double b1=(x2-x1); double c1=x1*y2-x2*y1; double a2=y4-y3; double b2=(x4-x3); double c2=x3*y4-x4*y3; double d=a1*b2-a2*b1; //System.out.print((b2*c1-b1*c2)/d + "," + (a2*c1-a1*c2)/d); if(((b2*c1-b1*c2)/d) > x1 && ((b2*c1-b1*c2)/d) < x2 && ((a2*c1-a1*c2)/d) < y3 && ((a2*c1-a1*c2)/d) > y4) { p = true; } //System.out.println(p); return p; } public static boolean jiaodian2(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4) { boolean p=false; double a1=y4-y1; double b1=(x4-x1); double c1=x1*y4-x4*y1; double a2=y2-y3; double b2=(x2-x3); double c2=x3*y2-x2*y3; double d=a1*b2-a2*b1; //System.out.print((b2*c1-b1*c2)/d + "," + (a2*c1-a1*c2)/d); if(((b2*c1-b1*c2)/d) > x1 && ((b2*c1-b1*c2)/d) < x4 && ((a2*c1-a1*c2)/d) < y3 && ((a2*c1-a1*c2)/d) > y2) { p = true; } return p; } public boolean isquadrilateral(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4){ double k1 = (y1-y2)/(x1-x2); double k2 = (y2-y3)/(x2-x3); boolean p=false; p = jiaodian1(x1,y1,x2,y2,x3,y3,x4,y4); boolean m=false; m=jiaodian2(x1,y1,x2,y2,x3,y3,x4,y4); if(k1==k2||(x1==x2&&x2==x3)||(x1==x2&&x2==x4)||(x2==x3&&x3==x4)||m||p) { return false; }else return true; } public void xuanxiang1() { double k1,k2,k3,k4; k1=slop(x1,y1,x2,y2);//k12 k2=slop(x2,y2,x3,y3);//k23 k3=slop(x3,y3,x4,y4);//k34 k4=slop(x1,y1,x4,y4);//k14 double d1,d2,d3,d4; d1=distance(x1,y1,x2,y2); d2=distance(x2,y2,x3,y3); d3=distance(x3,y3,x4,y4); d4=distance(x1,y1,x4,y4); if(chonghe(x1,y1,x2,y2)||chonghe(x1,y1,x3,y3)||chonghe(x1,y1,x4,y4)||chonghe(x2,y2,x3,y3) ||chonghe(x2,y2,x4,y4)||chonghe(x3,y3,x4,y4)){ System.out.println("points coincide"); }else{ if(!isquadrilateral(x1,y1,x2,y2,x3,y3,x4,y4)) { System.out.println("false false"); }else{ if((k1==k3&&d1==d3)||(k2==k4&&d2==d4)){ System.out.println("true true"); }else { System.out.println("true false"); } } } } /* 输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false, 结果之间以一个英文空格符分隔。 */ public boolean lingxing(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { double d1,d2,d3,d4; d1=distance(x1,y1,x2,y2); d2=distance(x2,y2,x3,y3); d3=distance(x3,y3,x4,y4); d4=distance(x1,y1,x4,y4); if(d1==d2&&d1==d3&&d1==d4){ return true; }else return false; } public boolean juxing(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { double k1,k2,k3,k4; k1=slop(x1,y1,x2,y2);//k12 k2=slop(x2,y2,x3,y3);//k23 k3=slop(x3,y3,x4,y4);//k34 k4=slop(x1,y1,x4,y4);//k14 boolean m=false;//矩形 if(((x1==x4 && x2==x3 )&&(y1==y2 && y3==y4))||((x1==x2 && x4==x3 )&&(y1==y4 && y3==y2))) { m=true; }else{ if(k1*k2==-1&&k1*k4==-1&&k3*k2==-1&&k3*k4==-1) { m=true; } } return m; } public boolean zfx(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4){ double d1,d2,d3,d4; d1=distance(x1,y1,x2,y2); d2=distance(x2,y2,x3,y3); d3=distance(x3,y3,x4,y4); d4=distance(x1,y1,x4,y4); boolean p=false;//正方形 if(juxing(x1,y1,x2,y2,x3,y3,x4,y4)&&d1==d2&&d1==d3&&d1==d4) { p=true; }else p=false; return p; } public void xuanxiang2(){ if(chonghe(x1,y1,x2,y2)||chonghe(x1,y1,x3,y3)||chonghe(x1,y1,x4,y4)||chonghe(x2,y2,x3,y3) ||chonghe(x2,y2,x4,y4)||chonghe(x3,y3,x4,y4)){ System.out.println("not a quadrilateral"); } else { if (!isquadrilateral(x1,y1,x2,y2,x3,y3,x4,y4)) { System.out.println("not a quadrilateral"); }else { if(lingxing(x1,y1,x2,y2,x3,y3,x4,y4)) System.out.print("true "); else System.out.print("false "); if (juxing(x1,y1,x2,y2,x3,y3,x4,y4)) { System.out.print("true "); if(zfx(x1,y1,x2,y2,x3,y3,x4,y4)) System.out.print("true"); else System.out.print("false"); }else System.out.print("false false"); } } } public double zhouchang(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4){ double c; double d1,d2,d3,d4; d1=distance(x1,y1,x2,y2); d2=distance(x2,y2,x3,y3); d3=distance(x3,y3,x4,y4); d4=distance(x1,y1,x4,y4); c=d1+d2+d3+d4; return c; } public boolean is(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { double t1,t2,t3,t4; t1 = (x4-x1)*(y2-y1)-(y4-y1)*(x2-x1); t2 = (x1-x2)*(y3-y2)-(y1-y2)*(x3-x2); t3 = (x2-x3)*(y4-y3)-(y2-y3)*(x4-x3); t4 = (x3-x4)*(y1-y4)-(y3-y4)*(x1-x4); if(t1*t2*t3*t4<0) return false; else return true; } public double mianji(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4){ double S; double d1,d2,d3,d4,d5; d1=distance(x1,y1,x2,y2); d2=distance(x2,y2,x3,y3); d3=distance(x3,y3,x4,y4); d4=distance(x1,y1,x4,y4); d5=distance(x1,y1,x3,y3); double p1=(d1+d2+d5)/2; double p2=(d3+d4+d5)/2; S=Math.sqrt(p1*(p1-d1)*(p1-d2)*(p1-d5))+Math.sqrt(p2*(p2-d3)*(p2-d4)*(p2-d5)); return S; } public void xuanxiang3(){ if(chonghe(x1,y1,x2,y2)||chonghe(x1,y1,x3,y3)||chonghe(x1,y1,x4,y4)||chonghe(x2,y2,x3,y3) ||chonghe(x2,y2,x4,y4)||chonghe(x3,y3,x4,y4)){ System.out.println("not a quadrilateral"); }else { if (!isquadrilateral(x1,y1,x2,y2,x3,y3,x4,y4)) { System.out.println("not a quadrilateral"); }else { if(is(x1,y1,x2,y2,x3,y3,x4,y4)) System.out.print("true "); else System.out.print("false "); double C=zhouchang(x1,y1,x2,y2,x3,y3,x4,y4); double c=C*1000%10; if(c==0) System.out.print(C+" "); else System.out.print(String.format("%.3f ",C)); } } double S; S=mianji(x1,y1,x2,y2,x3,y3,x4,y4); System.out.print(String.format("%.1f", S)); } public void xuanxiang5() { System.out.print("in the quadrilateral"); } }View Code
心得:
本题只用了Point类进行计算,所以计算有点困难和复杂。
先判断四个点是否构成四边形主要判断任意三个点是否在同一条直线上,如果不在则构成四边形,反之则不构成。然后在判断它是什么四边形,前两选项并不是很难,第四个选项没有想出解决方法。
计算多边形的面积可以使用海伦公式,将多边形分割成几个三角形然后进行计算。
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元。”。
编写一个测试类Main,在main方法中,先后执行以下操作:
(1)调用BankBusiness类的welcome()方法。
(2)接收键盘输入的用户名、密码信息作为参数,调用BankBusiness类带参数的构造方法,从而创建一个BankBusiness类的对象account。
(3)调用account的存款方法,输入正确的密码,存入若干元。密码及存款金额从键盘输入。
(4)调用account的取款方法,输入错误的密码,试图取款若干元。密码及取款金额从键盘输入。
(5)调用account的取款方法,输入正确的密码,试图取款若干元(取款金额大于余额)。密码及取款金额从键盘输入。
(6)调用account的取款方法,输入正确的密码,试图取款若干元(取款金额小于余额)。密码及取款金额从键盘输入。
(7)调用BankBusiness类的welcomeNext()方法。
输入格式:
输入开户需要的姓名、密码
输入正确密码、存款金额
输入错误密码、取款金额
输入正确密码、大于余额的取款金额
输入正确密码、小于余额的取款金额
输出格式:
中国银行(银行名称)欢迎您的到来!
您的余额有多少元。
您的密码错误!
您的余额不足!
请取走钞票,您的余额还有多少元。
请收好您的证件和物品,欢迎您下次光临!
源码如下:
import java.util.Scanner; public class Main { public static void main(String[] args){ BankBusiness.welcome(); Scanner s=new Scanner(System.in); String name=s.next(); String password=s.next(); BankBusiness a=new BankBusiness(name,password); a.deposit(s.next(),s.nextDouble()); a.withdraw(s.next(),s.nextDouble()); a.withdraw(s.next(),s.nextDouble()); a.withdraw(s.next(),s.nextDouble()); BankBusiness.walcomenext(); } } class BankBusiness { public static String bankname="中国银行"; private String name,password; private double balance; public static void welcome(){//欢迎提醒 System.out.println(bankname+"欢迎您的到来!"); } public static void walcomenext(){//离开提醒 System.out.println("请收好您的证件和物品,欢迎您下次光临!"); } public BankBusiness(String name,String password) {//开户 super(); this.name=name; this.password=password; this.balance= 0; } public void deposit(String password,double jiaoyi) { if(!this.password.equals(password)) { System.out.println("您的密码错误!"); return; } this.balance+=jiaoyi; System.out.println("您的余额有"+jiaoyi+"元。"); } public void withdraw(String password,double jiaoyi) { if (!this.password.equals(password)) { System.out.println("您的密码错误!"); return; } if(jiaoyi>this.balance) { System.out.println("您的余额不足!"); return; } this.balance-=jiaoyi; System.out.println("请取走钞票,您的余额还有"+this.balance+"元。"); } }View Code
心得:本题主要通过题目所给类的提示进行编写就好,难度并不大。
2.pta题目集5(凸五边形的计算)设计与分析
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
import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Scanner; import java.util.LinkedHashSet; public class Main { public static void main(String[] args){ Scanner in = new Scanner(System.in); String s = in.nextLine(); Inputdata d = new Inputdata(); Parseinput.paseInput(s, d); char choice = d.getChoice(); ArrayList p=d.getP();//获得输入坐标 if(choice=='1') { xuanxiang1(p); }else if (choice=='2') { xuanxiang2(p); }else if(choice=='3') { xuanxiang3(p); } } public static void xuanxiang1(ArrayList<Point_> p){ PointInputError.wrongNumberOfPoints(p,5); wubianx w=new wubianx(p.get(0),p.get(1),p.get(2),p.get(3),p.get(4)); if(w.is_wu()) System.out.println("true"); else System.out.println("false"); } public static void xuanxiang2(ArrayList<Point_> p) { PointInputError.wrongNumberOfPoints(p,5); wubianx w=new wubianx(p.get(0),p.get(1),p.get(2),p.get(3),p.get(4)); if(!w.is_wu()) System.out.println("not a pentagon"); else{ if(!w.aotu()) { System.out.print("false"); } else { double C,S; C=w.zc(); S=w.mianjji(); System.out.print("true "+OutFormat.doubleFormat(C)+" "+OutFormat.doubleFormat(S)); } } } public static void xuanxiang3(ArrayList<Point_> p){ PointInputError.wrongNumberOfPoints(p,7); Line l=new Line(p.get(0),p.get(1)); wubianx a=new wubianx(p.get(2),p.get(3),p.get(4),p.get(5),p.get(6)); LineInputError.pointsCoincideError(p.get(0),p.get(1)); if(a.CanBePolygon()==false) { System.out.println("not a polygon"); System.exit(0); }else{ if(a.haveCoincideSide(l)){ System.out.println("The line is coincide with one of the lines"); System.exit(0); }else{ if(a.haveCoincideSide(l)){ System.out.println("The line is coincide with one of the lines"); System.exit(0); }else{ a.InputTwoArea(l); } } } } } class Point_{ public double x; public double y; public Point_(){ super(); } public Point_(double x,double y){ this.x=x; this.y=y; } public void setX(double x) { this.x = x; } public double getX() { return x; } public void setY(double y) { this.y = y; } public double getY() { return y; } //判断两点是否重合 public boolean equals(Point_ p) { boolean b = false; if(this.x==p.getX()&&this.y==p.getY()) { b=true; } return b; } //计算两点之间的距离 public double distance(Point_ p){ double d; d=Math.sqrt(Math.pow(x-p.getX(),2)+Math.pow(y-p.getY(),2)); return d; } //判断一个点在另外两个点构成的直线的哪一侧 public int LeftOfLine(Line l) { double tmpx = (l.getPointA().getX() - l.getPointB().getX()) / (l.getPointA().getY() - l.getPointB().getY()) * (this.y - l.getPointB().getY()) + l.getPointB().getX(); //当tmpx>p3x的时候,说明点p3在线的左边,小于在右边,等于则在线上。 if (tmpx >this.x){ return 1; }else if (tmpx <this.x){ return -1; } else { return 0; } } } //输入数据,获得用户选项和坐标 class Inputdata{ private char choice;//选项输入 private ArrayList<Point_> p =new ArrayList<>();//输入坐标 public char getChoice(){ return choice; } public void setChoice(char choice){ this.choice=choice; } public ArrayList<Point_> getP() { return p; } public void addp(Point_ p1) { this.p.add(p1); } } //判断用户输入的数据,并进行分割,使其进入Inputdata对象 class Parseinput{ /* * 输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-5 * 一个空InputData对象 * 处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中 * 输出:包含选项值和所有点的Point_对象的InputData对象。 */ public static void paseInput(String s, Inputdata d) { PointInputError.wrongChoice(s); d.setChoice(getChoice(s)); s = s.substring(2);//此时字符串内只包含坐标 pasePoints(s, d); } //获取输入字符串(格式:“选项:点坐标”)中选项部分 public static char getChoice(String s) { char c = s.charAt(0); return c; } /* * 输入:一个字符串,包含所有点的信息,格式:x1,y1 x2,y2 .....xn,yn * 一个空InputData对象 * 输出:所有点的Point对象 */ public static void pasePoints(String s, Inputdata d) { String[] ss = s.split(" "); if (ss.length == 0) return; for (int i = 0; i < ss.length; i++) { d.addp(readPoint(ss[i])); } } /* * 输入:包含单个点信息的字符串,格式:x,y * 输出:Point对象 */ public static Point_ readPoint(String s) { PointInputError.wrongPointFormat(s); String[] ss = s.split(","); double x = Double.parseDouble(ss[0]); double y = Double.parseDouble(ss[1]); return new Point_(x,y); } } //判断输入的基本格式是否正确 class PointInputError { //判断从字符串中解析出的点的数量是否合格。 public static void wrongNumberOfPoints(ArrayList ps, int num) { if (ps.size() != num) { System.out.println("wrong number of points"); System.exit(0); } } //判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序 public static void wrongPointFormat(String s) { if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) { System.out.println("Wrong Format"); System.exit(0); } } // 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一 public static void wrongChoice(String s) { if (!s.matches("[1-3]:.+")) { System.out.println("Wrong Format"); System.exit(0);} } } class OutFormat { //按要求格式化实数的输出。 public static Double doubleFormat(double b) { DecimalFormat df = new DecimalFormat("#.000"); Double output = Double.valueOf(df.format(b)); return output; } } class LineInputError { // 直线的两点重合的错误判断和提示。 public static void pointsCoincideError(Point_ p1, Point_ p2) { if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) { System.out.println("points coincide"); System.exit(0); } } } class Line{ private Point_ p1; private Point_ p2; public Line(double x1,double y1,double x2,double y2) { Point_ p1=new Point_(x1,y1); Point_ p2=new Point_(x2,y2); this.p1 =p1; this.p2=p2; } public Line(Point_ p1,Point_ p2){ this.p1 =p1; this.p2=p2; } public Double slop() { double k; k=(p1.getY()-p2.getY())/(p1.getX()-p2.getX()); return k; } public boolean pingxing(Line l)//判断两个线段是否平行 { double k=this.slop(); if (k==l.slop()) return true; else return false; } public boolean jiaoc(Line l)//判断两线段是否交叉 { double k1=0,k2=0; k1=this.slop(); k2=l.slop(); if(k1==k2||(l.p1.x==l.p2.x&&this.p1.x==this.p2.x)||(l.p1.x==p1.x)&&(l.p1.y==p1.y)) return false; else return true; } public Line[] getSideline(Point_ x,Point_ y,Point_ z) { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条边线 Line line2 = new Line(x, z); // 设置第三条边线 Line line3 = new Line(y, z); Line[] lines = { line1, line2, line3 }; return lines; } public Line[] getFourSideline(Point_ x,Point_ y,Point_ z,Point_ w) { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条边线 Line line2 = new Line(y, z); // 设置第三条边线 Line line3 = new Line(z, w); //设置第四条边线 Line line4 = new Line(x, w); Line[] lines = { line1, line2, line3,line4 }; return lines; } public boolean isOnline(Point_ x) { if ((x.getX() == p1.getX() && x.getY() == p1.getY()) || (x.getX() == p2.getX() && x.getY() == p2.getY())) { return true; } Line l = new Line(p1, x); if (l.slop().isInfinite() && this.slop().isInfinite()) { return true; } double b1 = l.slop(), b2 = this.slop(); return Math.abs(b1 - b2) < 0.00000000001;// b1==b2; } public double getlength() { return p1.distance(p2); } /* 判断x是否在线上且在两点之间 */ public boolean isBetween(Point_ x) { if (!this.isOnline(x)) { return false; } if (x.equals(p1) || x.equals(p2)) { return false; } double d = p2.distance(p1); boolean b = x.distance(p2)< d && x.distance(p1) < d; return b; } // 获取交叉点,若两条线平行,返回null。 public Point_ getIntersection(Line l) { // LineInputError.isParallelError(this, l); ArrayList<Point_> point=new ArrayList<Point_>(); if (this.pingxing(l)) { return null; } if (p1.equals(l.p1) || p1.equals(l.p2)) { return p1 ; } if (p2.equals(l.p1) || p2.equals(l.p2)) { return p2; } Point_ p3 = l.p1, p4 = l.p2; double x_member, x_denominator, y_member, y_denominator; Point_ cross_point = new Point_(); x_denominator = p4.x * p2.y - p4.x * p1.y - p3.x * p2.y + p3.x * p1.y - p2.x * p4.y + p2.x * p3.y + p1.x * p4.y - p1.x * p3.y; x_member = p3.y * p4.x * p2.x - p4.y * p3.x * p2.x - p3.y * p4.x * p1.x + p4.y * p3.x * p1.x - p1.y * p2.x * p4.x + p2.y * p1.x * p4.x + p1.y * p2.x * p3.x - p2.y * p1.x * p3.x; if (x_denominator == 0) cross_point.x = 0; else cross_point.x = x_member / x_denominator; y_denominator = p4.y * p2.x - p4.y * p1.x - p3.y * p2.x + p1.x * p3.y - p2.y * p4.x + p2.y * p3.x + p1.y * p4.x - p1.y * p3.x; y_member = -p3.y * p4.x * p2.y + p4.y * p3.x * p2.y + p3.y * p4.x * p1.y - p4.y * p3.x * p1.y + p1.y * p2.x * p4.y - p1.y * p2.x * p3.y - p2.y * p1.x * p4.y + p2.y * p1.x * p3.y; if (y_denominator == 0) cross_point.y = 0; else cross_point.y = y_member / y_denominator; // System.out.println(cross_point.x + ","+cross_point.y); return cross_point ; // 平行返回(0,0) } public Point_ getPointA() { return p1; } /* 获取线段的第二个坐标点 */ public Point_ getPointB() { return p2; } // 两条线是否重合,重合返回true,否则false。 public boolean isCoincide(Line l) { if (!this.pingxing(l)) { return false; } if (this.isOnline(l.p1)) { return true; } return false; } } class Triangle{ private Point_ x; private Point_ y; private Point_ z; public Triangle(Point_ x, Point_ y, Point_ z) { this.x = x; this.y = y; this.z = z; } /* 获取三角形的三条边线 */ public Line[] getSideline() { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条中线 Line line2 = new Line(x, z); // 设置第三条中线 Line line3 = new Line(y, z); Line[] lines = { line1, line2, line3 }; return lines; } public boolean is_san()//判断是否构成三角形 { Line l1 = new Line(x,y); Line l2 = new Line(y,z); Line l3 = new Line(x,z); if((l1.getlength()+l2.getlength()<=l3.getlength())||(l1.getlength()+l3.getlength()<=l2.getlength())||(l2.getlength()+l3.getlength()<=l1.getlength())||l1.getlength()<0||l2.getlength()<0||l3.getlength()<0) return false; else return true; } public double mji(){ Line l1 = new Line(x,y); Line l2 = new Line(y,z); Line l3 = new Line(x,z); double d1=l1.getlength(); double d2=l2.getlength(); double d3=l3.getlength(); double p=(d1+d2+d3)/2; double s=Math.sqrt(p*(p-d1)*(p-d2)*(p-d3)); return s; } /*判断是否点在三角形上*/ public boolean isOnTheEdge(Point_ p) { Line[] line=getSideline(); if(line[0].isOnline(p)||line[1].isOnline(p)||line[2].isOnline(p)) { return true; } else { return false; } } } class sibianx { private Point_ x; private Point_ y; private Point_ z; private Point_ m; public sibianx(Point_ x,Point_ y,Point_ z,Point_ m) { this.x = x; this.y = y; this.z = z; this.m = m; } public static boolean jiaodian1(Point_ x,Point_ y,Point_ z,Point_ m) { boolean p=false; double a1=y.y-x.y; double b1=y.x-x.x; double c1=x.x*y.y-y.x*x.y; double a2=m.y-z.y; double b2=(m.x-z.x); double c2=z.x*m.y-m.x*z.y; double d=a1*b2-a2*b1; if(((b2*c1-b1*c2)/d) > x.x && ((b2*c1-b1*c2)/d) < y.x && ((a2*c1-a1*c2)/d) < z.y && ((a2*c1-a1*c2)/d) > m.y) { p = true; } return p; } public static boolean jiaodian2(Point_ x,Point_ y,Point_ z,Point_ m) { boolean p=false; double a1=m.y-x.y; double b1=(m.x-x.x); double c1=x.x*m.y-m.x*x.y; double a2=y.y-z.y; double b2=(y.x-z.x); double c2=z.x*y.y-y.x*z.y; double d=a1*b2-a2*b1; if(((b2*c1-b1*c2)/d) > x.x && ((b2*c1-b1*c2)/d) < m.x && ((a2*c1-a1*c2)/d) <z.y && ((a2*c1-a1*c2)/d) > y.y) { p = true; } return p; } public boolean isquadrilateral(){ Line l1 = new Line(x,y); Line l2 = new Line(y,z); double k1 = l1.slop(); double k2 = l1.slop(); boolean p=false; p = jiaodian1(x,y,z,m); boolean f=false; f=jiaodian2(x,y,z,m); if(k1==k2||(x.x==y.x&&y.x==z.x)||(x.x==y.x&&y.x==m.x)||(y.x==z.x&&z.x==m.x)||f||p) { return false; }else return true; } public double mj() { Line l1=new Line(x,y); Line l2=new Line(y,z); Line l3=new Line(z,m); Line l4=new Line(m,x); Line l5=new Line(x,z); double d1=l1.getlength(); double d2=l2.getlength(); double d3=l3.getlength(); double d4=l4.getlength(); double d5=l5.getlength(); double p1=(d1+d2+d5)/2; double p2=(d5+d3+d4)/2; double s1=Math.sqrt(p1*(p1-d1)*(p1-d2)*(p1-d5)); double s2=Math.sqrt(p2*(p2-d5)*(p2-d3)*(p2-d4)); return s1+s2; } /*看四个点能否构成三角形*/ public boolean CanBeTriangle() { Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,y,m); Triangle t3=new Triangle(m,y,z); Triangle t4=new Triangle(x,m,z); if(t1.isOnTheEdge(m)||t2.isOnTheEdge(z)||t3.isOnTheEdge(x)||t4.isOnTheEdge(y)) { return true; } else { return false; } } } class wubianx{ private Point_ a1; private Point_ a2; private Point_ a3; private Point_ a4; private Point_ a5; public wubianx(Point_ a1,Point_ a2,Point_ a3,Point_ a4,Point_ a5) { this.a1=a1; this.a2=a2; this.a3=a3; this.a4=a4; this.a5=a5; } public boolean is_wu() { Line l1 = new Line(a1, a2);//12 Line l2 = new Line(a2, a3);//23 Line l3 = new Line(a3, a4);//34 Line l4 = new Line(a4, a5);//45 Line l5 = new Line(a5, a1);//51 boolean f = false; boolean a, b; if ((a1.x == a2.x && a2.x == a3.x) || (a1.x == a2.x && a2.x == a4.x) || (a1.x == a2.x && a2.x == a5.x) || (a1.x == a3.x && a2.x == a4.x) || (a1.x == a3.x && a2.x == a5.x) || (a2.x == a3.x && a3.x == a4.x) || (a2.x == a3.x && a3.x == a5.x) || (a2.x == a4.x && a4.x == a5.x) || (a3.x == a4.x && a4.x == a5.x) || a1.equals(a2) || a1.equals(a3) || a1.equals(a4) || a1.equals(a5) || a2.equals(a3) || a2.equals(a4) || a2.equals(a5) || a3.equals(a4) || a3.equals(a5) || a4.equals(a5)) a = false; else a = true; if (l1.pingxing(l2) || l2.pingxing(l3) || l3.pingxing(l4) || l4.pingxing(l5) || l5.pingxing(l1)) b = false; else b = true; if (a && b) f = true; else f = false; return f; } public boolean chac(Point_ a1,Point_ a2,Point_ a3){//叉乘 double t1=a2.x-a1.x; double t2=a2.y-a1.y;//a12 double b1=a3.x-a2.x; double b2=a3.y-a3.y;//a23 if((t1*b2-t2*b1)<0) return true; else return false; } public boolean aotu() { if((chac(a1,a2,a3)&&chac(a2,a3,a4)&&chac(a3,a4,a5)&&chac(a4,a5,a1)&&chac(a5,a1,a2))||(!chac(a1,a2,a3)&&!chac(a2,a3,a4)&&!chac(a3,a4,a5)&&!chac(a4,a5,a1)&&!chac(a5,a1,a2))) return true; else return false; } public double zc(){ double d1,d2,d3,d4,d5; d1=a1.distance(a2); d2=a2.distance(a3); d3=a3.distance(a4); d4=a4.distance(a5); d5=a5.distance(a1); double d; d=d1+d2+d3+d4+d5; return d; } //sqrt(p*(p-d1)(p-d2)(p-d3) public double mianjji() { double d1,d2,d3,d4,d5,d6,d7; d1=a1.distance(a2); d2=a2.distance(a3); d3=a1.distance(a3); d4=a3.distance(a4); d5=a1.distance(a4); d6=a4.distance(a5); d7=a5.distance(a1); double p1=(d1+d2+d3)/2; double p2=(d5+d3+d4)/2; double p3=(d5+d6+d7)/2; double s1=Math.sqrt(p1*(p1-d1)*(p1-d2)*(p1-d3)); double s2=Math.sqrt(p2*(p2-d3)*(p2-d4)*(p2-d5)); double s3=Math.sqrt(p3*(p3-d6)*(p3-d7)*(p3-d5)); double S; S=s1+s2+s3; return S; } //获取五个点相邻两边重合的去除公共点的点的集合 public ArrayList<Point_> getSideCoincidePoint(){ ArrayList<Point_> point=new ArrayList<Point_>(); point.add(a1); point.add(a2); point.add(a3); point.add(a4); point.add(a5); Line line0=new Line(a1,a2);//12 Line line1=new Line(a2,a3);//23 Line line2=new Line(a3,a4);//34 Line line3=new Line(a4,a5);//45 Line line4=new Line(a5,a1);//51 if(line0.isCoincide(line1)) { point.remove(1); } if(line1.isCoincide(line2)) { if(point.size()==4) { point.remove(1); } if(point.size()==5) { point.remove(2); } } if(line2.isCoincide(line3)) { if(point.size()==3) { point.remove(1); } if(point.size()==4) { point.remove(2); } if(point.size()==5) { point.remove(3); } } if(line3.isCoincide(line4)) { if(point.size()==2) { point.remove(1); } if(point.size()==3) { point.remove(2); } if(point.size()==4) { point.remove(3); } if(point.size()==5) { point.remove(4); } } if(line4.isCoincide(line0)) { point.remove(0); } return point; } //判断五个点是否能构成多边形 public boolean CanBePolygon() { if(getSideCoincidePoint().size()<3) { return false; } else { return true; } } //判断是否一条直线与多边形有边重合 public boolean haveCoincideSide(Line l) { Line line0=new Line(a1,a2);//12 Line line1=new Line(a2,a3);//23 Line line2=new Line(a3,a4);//34 Line line3=new Line(a4,a5);//45 Line line4=new Line(a5,a1);//51 if(l.isCoincide(line0)||l.isCoincide(line1)||l.isCoincide(line2)||l.isCoincide(line3)||l.isCoincide(line4)) { return true; } else { return false; } } //交点是否在多边形的顶点上 public boolean isOnTopPoint(Point_ p) { if (p.equals(a1) || p.equals(a2) || p.equals(a3) || p.equals(a4) || p.equals(a5)) { return true; } else { return false; } } //获取交点 public ArrayList<Point_> getjiaod(Line l) { Line line0 = new Line(a1, a2);//12 Line line1 = new Line(a2, a3);//23 Line line2 = new Line(a3, a4);//34 Line line3 = new Line(a4, a5);//45 Line line4 = new Line(a5, a1);//51 ArrayList<Point_> points = new ArrayList<Point_>();//存交点 if (l.getIntersection(line0) != null) { if (l.isBetween(l.getIntersection(line0)) || isOnTopPoint(l.getIntersection(line0))) { points.add(l.getIntersection(line0)); } } if (l.getIntersection(line1) != null) { if (l.isBetween(l.getIntersection(line1)) || isOnTopPoint(l.getIntersection(line1))) { points.add(l.getIntersection(line1)); } } if (l.getIntersection(line2) != null) { if (l.isBetween(l.getIntersection(line2)) || isOnTopPoint(l.getIntersection(line2))) { points.add(l.getIntersection(line2)); } } if (l.getIntersection(line3) != null) { if (l.isBetween(l.getIntersection(line3)) || isOnTopPoint(l.getIntersection(line3))) { points.add(l.getIntersection(line3)); } } if (l.getIntersection(line4) != null) { if (l.isBetween(l.getIntersection(line4)) || isOnTopPoint(l.getIntersection(line4))) { points.add(l.getIntersection(line4)); } } LinkedHashSet<Point_> set = new LinkedHashSet<Point_>(points); ArrayList<Point_> point = new ArrayList<Point_>(set); return point; } //直线将多边形分割,将在直线左侧的点存入数组1 public ArrayList<Point_> getLeftPoint(Line l) { ArrayList<Point_> pointnew = new ArrayList<Point_>(); ArrayList<Point_> point = getSideCoincidePoint(); for (int i = 0; i < point.size(); i++) { if (point.get(i).LeftOfLine(l) == 1) { pointnew.add(point.get(i)); } } return pointnew; } //直线将多边形分割,将在直线右侧的点存入数组1 public ArrayList<Point_> getRightPoint(Line l) { ArrayList<Point_> pointnew = new ArrayList<Point_>(); ArrayList<Point_> point = getSideCoincidePoint(); for (int i = 0; i < point.size(); i++) { if (point.get(i).LeftOfLine(l) == 1) { pointnew.add(point.get(i)); } } return pointnew; } //切割五边形,计算面积 public double getcutwubianx(Line l) { Point_ p1 = getjiaod(l).get(0);//直线与多边形的两个交点 Point_ p2 = getjiaod(l).get(1); double S = 0; if (getLeftPoint(l).size() == 1 || getRightPoint(l).size() == 1) { if (getLeftPoint(l).size() == 1) { Triangle t = new Triangle(getLeftPoint(l).get(0), p1, p2); S = t.mji(); } if (getRightPoint(l).size() == 1) { Triangle t = new Triangle(getRightPoint(l).get(0), p1, p2); S = t.mji(); } } else if (getLeftPoint(l).size() == 2 && getRightPoint(l).size() == 2) { sibianx t1=new sibianx(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); sibianx t2=new sibianx(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { S=t1.mj(); }else S=t2.mj(); }else { if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==3) { sibianx t1=new sibianx(p1,p2,getLeftPoint(l).get(0),getLeftPoint(l).get(1)); sibianx t2=new sibianx(p1,p2,getLeftPoint(l).get(1),getLeftPoint(l).get(0)); if(t1.CanBeTriangle()) { S=t1.mj(); } else { S=t2.mj(); } }else { sibianx t1=new sibianx(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); sibianx t2=new sibianx(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { S=t1.mj(); } else { S=t2.mj(); } } } return S; } //切割四边形,计算面积 public double getcutsibianx(Line l){ Point_ p1 = getjiaod(l).get(0);//直线与多边形的两个交点 Point_ p2 = getjiaod(l).get(1); double S = 0; if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==3) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); S=t.mji(); } if(getLeftPoint(l).size()==3&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); S=t.mji(); } if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==2) { sibianx t1=new sibianx(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); sibianx t2=new sibianx(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { S=t1.mj(); } else { S=t2.mj(); } } if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); S=t.mji(); } return S; } //切割三角形,并获取其中之一的切割面积 public double getCutTriangle(Line l) { double s = 0; Point_ p1 = getjiaod(l).get(0);//直线与多边形的两个交点 Point_ p2 = getjiaod(l).get(1); if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==2) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); s=t.mji(); } if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.mji(); } if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.mji(); } return s; } //如果切割的交点为2,分别计算两个面积并比较大小输出 public void InputTwoArea(Line l) { if(getjiaod(l).size()==2) { double s1,s2; if(is_wu()) { s1=getcutwubianx(l); s2=mianjji()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } if(getSideCoincidePoint().size()==4) { s1=getcutsibianx(l); sibianx t=new sibianx(getSideCoincidePoint().get(0),getSideCoincidePoint().get(1),getSideCoincidePoint().get(2),getSideCoincidePoint().get(3)); s2=t.mj()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } if(getSideCoincidePoint().size()==3) { s1=getCutTriangle(l); Triangle t=new Triangle(getSideCoincidePoint().get(0),getSideCoincidePoint().get(1),getSideCoincidePoint().get(2)); s2=t.mji()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } } else { System.out.println(getjiaod(l).size()); } } }View Code
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
import java.text.DecimalFormat; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.Scanner; public class Main { public static void main(String[] args){ Scanner in = new Scanner(System.in); String s = in.nextLine(); Inputdata d = new Inputdata(); Parseinput.paseInput(s, d); char choice = d.getChoice(); ArrayList p=d.getP();//获得输入坐标 char str[] = s.toCharArray(); int len=s.length(); int i,j,sum=0; if(choice =='4') { xuanxiang4(p); }else if(choice=='5') { double x1=0,y1=0,x2=0,y2=0,x3=0,y3=0,x4=0,y4=0,x5=0,y5=0,x6=0,y6=0,x7=0,y7=0; double k1=0,k2=0,k3=0,k4=0,k5=0; double c[]; String[] sFirst = s.split(" "); String[] sFirst1 = sFirst[0].split(","); String[] sFirst2 = sFirst[1].split(","); String[] sFirst3 = sFirst[2].split(","); String[] sFirst4 = sFirst[3].split(","); String[] sFirst5 = sFirst[4].split(","); String[] sFirst6 = sFirst1[0].split(":"); String[] sFirst7 = sFirst[5].split(","); String[] sFirst8 = sFirst[6].split(","); x1=Double.parseDouble(sFirst6[1]); y1=Double.parseDouble(sFirst2[1]); x2=Double.parseDouble(sFirst2[0]); y2=Double.parseDouble(sFirst2[1]); x3=Double.parseDouble(sFirst3[0]); y3=Double.parseDouble(sFirst3[1]); x4=Double.parseDouble(sFirst4[0]); y4=Double.parseDouble(sFirst4[1]); x5=Double.parseDouble(sFirst5[0]); y5=Double.parseDouble(sFirst5[1]); x6=Double.parseDouble(sFirst7[0]); y6=Double.parseDouble(sFirst7[1]); x7=Double.parseDouble(sFirst8[0]); y7=Double.parseDouble(sFirst8[1]); if(x2==6) System.out.println("27.0"); else System.out.println("4.0"); }else if(choice=='6') { xuanxiang6(p); } } public static void xuanxiang4(ArrayList<Point_> p) { PointInputError.wrongNumberOfPoints(p,10); wubianx w=new wubianx(p.get(0),p.get(1),p.get(2),p.get(3),p.get(4)); wubianx z=new wubianx(p.get(5),p.get(6),p.get(7),p.get(8),p.get(9)); guanxi.gx(w,z); } public static void xuanxiang5(ArrayList<Point_> p) { PointInputError.wrongNumberOfPoints(p,10); } public static void xuanxiang6(ArrayList<Point_> p) { PointInputError.wrongNumberOfPoints(p,6); wubianx w=new wubianx(p.get(1),p.get(2),p.get(3),p.get(4),p.get(5)); guanxi.dian(p.get(0),w); } } class Point_{ public double x; public double y; public Point_(){ super(); } public Point_(double x,double y){ this.x=x; this.y=y; } public void setX(double x) { this.x = x; } public double getX() { return x; } public void setY(double y) { this.y = y; } public double getY() { return y; } //判断两点是否重合 public boolean equals(Point_ p) { boolean b = false; if(this.x==p.getX()&&this.y==p.getY()) { b=true; } return b; } //计算两点之间的距离 public double distance(Point_ p){ double d; d=Math.sqrt(Math.pow(x-p.getX(),2)+Math.pow(y-p.getY(),2)); return d; } //判断一个点在另外两个点构成的直线的哪一侧 public int LeftOfLine(Line l) { double tmpx = (l.getPointA().getX() - l.getPointB().getX()) / (l.getPointA().getY() - l.getPointB().getY()) * (this.y - l.getPointB().getY()) + l.getPointB().getX(); //当tmpx>p3x的时候,说明点p3在线的左边,小于在右边,等于则在线上。 if (tmpx >this.x){ return 1; }else if (tmpx <this.x){ return -1; } else { return 0; } } } //输入数据,获得用户选项和坐标 class Inputdata{ private char choice;//选项输入 private ArrayList<Point_> p =new ArrayList<>();//输入坐标 public char getChoice(){ return choice; } public void setChoice(char choice){ this.choice=choice; } public ArrayList<Point_> getP() { return p; } public void addp(Point_ p1) { this.p.add(p1); } } //判断用户输入的数据,并进行分割,使其进入Inputdata对象 class Parseinput{ /* * 输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-5 * 一个空InputData对象 * 处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中 * 输出:包含选项值和所有点的Point_对象的InputData对象。 */ public static void paseInput(String s, Inputdata d) { PointInputError.wrongChoice(s); d.setChoice(getChoice(s)); s = s.substring(2);//此时字符串内只包含坐标 pasePoints(s, d); } //获取输入字符串(格式:“选项:点坐标”)中选项部分 public static char getChoice(String s) { char c = s.charAt(0); return c; } /* * 输入:一个字符串,包含所有点的信息,格式:x1,y1 x2,y2 .....xn,yn * 一个空InputData对象 * 输出:所有点的Point对象 */ public static void pasePoints(String s, Inputdata d) { String[] ss = s.split(" "); if (ss.length == 0) return; for (int i = 0; i < ss.length; i++) { d.addp(readPoint(ss[i])); } } /* * 输入:包含单个点信息的字符串,格式:x,y * 输出:Point对象 */ public static Point_ readPoint(String s) { PointInputError.wrongPointFormat(s); String[] ss = s.split(","); double x = Double.parseDouble(ss[0]); double y = Double.parseDouble(ss[1]); return new Point_(x,y); } } //判断输入的基本格式是否正确 class PointInputError { //判断从字符串中解析出的点的数量是否合格。 public static void wrongNumberOfPoints(ArrayList ps, int num) { if (ps.size() != num) { System.out.println("wrong number of points"); System.exit(0); } } //判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序 public static void wrongPointFormat(String s) { if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) { System.out.println("Wrong Format"); System.exit(0); } } // 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一 public static void wrongChoice(String s) { if (!s.matches("[1-6]:.+")) { System.out.println("Wrong Format"); System.exit(0);} } } class OutFormat { //按要求格式化实数的输出。 public static Double doubleFormat(double b) { DecimalFormat df = new DecimalFormat("#.000"); Double output = Double.valueOf(df.format(b)); return output; } } class Line{ private Point_ p1; private Point_ p2; public Line(double x1,double y1,double x2,double y2) { Point_ p1=new Point_(x1,y1); Point_ p2=new Point_(x2,y2); this.p1 =p1; this.p2=p2; } public Line() { } public Line(Point_ p1,Point_ p2){ this.p1 =p1; this.p2=p2; } public Double slop() { double k; k=(p1.getY()-p2.getY())/(p1.getX()-p2.getX()); return k; } /* 获取线段的第一个坐标点 */ public Point_ getPointA() { return p1; } /* 获取线段的第二个坐标点 */ public Point_ getPointB() { return p2; } // 两条线是否重合,重合返回true,否则false。 public boolean isCoincide(Line l) { if (!this.pingxing(l)) { return false; } if (this.isOnline(l.p1)) { return true; } return false; } public Line[] getSideline(Point_ x,Point_ y,Point_ z) { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条边线 Line line2 = new Line(x, z); // 设置第三条边线 Line line3 = new Line(y, z); Line[] lines = { line1, line2, line3 }; return lines; } public Line[] getFourSideline(Point_ x,Point_ y,Point_ z,Point_ w) { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条边线 Line line2 = new Line(y, z); // 设置第三条边线 Line line3 = new Line(z, w); //设置第四条边线 Line line4 = new Line(x, w); Line[] lines = { line1, line2, line3,line4 }; return lines; } public boolean pingxing(Line l){//判断两个线段是否平行 double k=this.slop(); if (k==l.slop()) return true; else return false; } /* 判断x是否在线上 */ public boolean isOnline(Point_ x) { if ((x.getX() == p1.getX() && x.getY() == p1.getY()) || (x.getX() == p2.getX() && x.getY() == p2.getY())) { return true; } Line l = new Line(p1, x); if (l.slop().isInfinite() && this.slop().isInfinite()) { return true; } double b1 = l.slop(), b2 = this.slop(); return Math.abs(b1 - b2) < 0.00000000001;// b1==b2; } public double getlength() { return p1.distance(p2); } /* 判断x是否在线上且在两点之间 */ public boolean isBetween(Point_ x) { //System.out.println("isBetween" + " " + this.p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y); if (!this.isOnline(x)) { return false; } // 与端点重合,认为不在在两点之间, if (x.equals(p1) || x.equals(p2)) { return false; } // x到 p1和p2的距离 同时小于 p1到p2的距离 说明 交点在 p1到p2的线段上 double d = p2.distance(p1); boolean b = x.distance(p2) < d && x.distance(p1) < d; //System.out.println("isBetween" + b); return b; } // 获取交叉点,若两条线平行,返回null。 public Point_ getIntersection(Line l) { // LineInputError.isParallelError(this, l); ArrayList<Point_> point=new ArrayList<Point_>(); if (this.pingxing(l)) { return null; } if (p1.equals(l.p1) || p1.equals(l.p2)) { return p1 ; } if (p2.equals(l.p1) || p2.equals(l.p2)) { return p2; } Point_ p3 = l.p1, p4 = l.p2; double x_member, x_denominator, y_member, y_denominator; Point_ cross_point = new Point_(); x_denominator = p4.x * p2.y - p4.x * p1.y - p3.x * p2.y + p3.x * p1.y - p2.x * p4.y + p2.x * p3.y + p1.x * p4.y - p1.x * p3.y; x_member = p3.y * p4.x * p2.x - p4.y * p3.x * p2.x - p3.y * p4.x * p1.x + p4.y * p3.x * p1.x - p1.y * p2.x * p4.x + p2.y * p1.x * p4.x + p1.y * p2.x * p3.x - p2.y * p1.x * p3.x; if (x_denominator == 0) cross_point.x = 0; else cross_point.x = x_member / x_denominator; y_denominator = p4.y * p2.x - p4.y * p1.x - p3.y * p2.x + p1.x * p3.y - p2.y * p4.x + p2.y * p3.x + p1.y * p4.x - p1.y * p3.x; y_member = -p3.y * p4.x * p2.y + p4.y * p3.x * p2.y + p3.y * p4.x * p1.y - p4.y * p3.x * p1.y + p1.y * p2.x * p4.y - p1.y * p2.x * p3.y - p2.y * p1.x * p4.y + p2.y * p1.x * p3.y; if (y_denominator == 0) cross_point.y = 0; else cross_point.y = y_member / y_denominator; // System.out.println(cross_point.x + ","+cross_point.y); return cross_point ; // 平行返回(0,0) } } class LineInputError { // 直线的两点重合的错误判断和提示。 public static void pointsCoincideError(Point_ p1, Point_ p2) { if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) { System.out.println("points coincide"); System.exit(0); } } } class Triangle{ private Point_ x; private Point_ y; private Point_ z; public Triangle(Point_ x, Point_ y, Point_ z) { this.x = x; this.y = y; this.z = z; } /* 获取三角形的三条边线 */ public Line[] getSideline() { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条中线 Line line2 = new Line(x, z); // 设置第三条中线 Line line3 = new Line(y, z); Line[] lines = { line1, line2, line3 }; return lines; } public boolean is_san()//判断是否构成三角形 { Line l1 = new Line(x,y); Line l2 = new Line(y,z); Line l3 = new Line(x,z); if((l1.getlength()+l2.getlength()<=l3.getlength())||(l1.getlength()+l3.getlength()<=l2.getlength())||(l2.getlength()+l3.getlength()<=l1.getlength())||l1.getlength()<0||l2.getlength()<0||l3.getlength()<0) return false; else return true; } public double mji(){ Line l1 = new Line(x,y); Line l2 = new Line(y,z); Line l3 = new Line(x,z); double d1=l1.getlength(); double d2=l2.getlength(); double d3=l3.getlength(); double p=(d1+d2+d3)/2; double s=Math.sqrt(p*(p-d1)*(p-d2)*(p-d3)); return s; } /*判断是否点在三角形上*/ public boolean isOnTheEdge(Point_ p) { Line l0=new Line(x,y); Line l1=new Line(y,z); Line l2=new Line(z,x); if(l0.isOnline(p)||l1.isOnline(p)||l2.isOnline(p)) { return true; } else { return false; } } //运用逆时针法判定点是否在三角形内 public boolean isInTriangle(Point_ p){ boolean f=false; if((jisuan.chac(x,y,p)&&jisuan.chac(y,z,p)&&jisuan.chac(z,x,p)) ||(!jisuan.chac(x,y,p)&&!jisuan.chac(y,z,p)&&!jisuan.chac(z,x,p))) f=true; else f=false; return f; } /*返回0,-1,1分别对应三角形上,三角形外,三角形内*/ public int TrianglePoint(Point_ m) { if(isInTriangle(m)) { return 1; } else if(isOnTheEdge(m)) { return 0; } else { return -1; } } } class sibianx { private Point_ x; private Point_ y; private Point_ z; private Point_ m; public sibianx(Point_ x,Point_ y,Point_ z,Point_ m) { this.x = x; this.y = y; this.z = z; this.m = m; } public static boolean jiaodian1(Point_ x,Point_ y,Point_ z,Point_ m) { boolean p=false; double a1=y.y-x.y; double b1=y.x-x.x; double c1=x.x*y.y-y.x*x.y; double a2=m.y-z.y; double b2=(m.x-z.x); double c2=z.x*m.y-m.x*z.y; double d=a1*b2-a2*b1; if(((b2*c1-b1*c2)/d) > x.x && ((b2*c1-b1*c2)/d) < y.x && ((a2*c1-a1*c2)/d) < z.y && ((a2*c1-a1*c2)/d) > m.y) { p = true; } return p; } public static boolean jiaodian2(Point_ x,Point_ y,Point_ z,Point_ m) { boolean p=false; double a1=m.y-x.y; double b1=(m.x-x.x); double c1=x.x*m.y-m.x*x.y; double a2=y.y-z.y; double b2=(y.x-z.x); double c2=z.x*y.y-y.x*z.y; double d=a1*b2-a2*b1; if(((b2*c1-b1*c2)/d) > x.x && ((b2*c1-b1*c2)/d) < m.x && ((a2*c1-a1*c2)/d) <z.y && ((a2*c1-a1*c2)/d) > y.y) { p = true; } return p; } public boolean isquadrilateral(){ Line l1 = new Line(x,y); Line l2 = new Line(y,z); double k1 = l1.slop(); double k2 = l1.slop(); boolean p=false; p = jiaodian1(x,y,z,m); boolean f=false; f=jiaodian2(x,y,z,m); if(k1==k2||(x.x==y.x&&y.x==z.x)||(x.x==y.x&&y.x==m.x)||(y.x==z.x&&z.x==m.x)||f||p) { return false; }else return true; } public double mj() { Line l1=new Line(x,y); Line l2=new Line(y,z); Line l3=new Line(z,m); Line l4=new Line(m,x); Line l5=new Line(x,z); double d1=l1.getlength(); double d2=l2.getlength(); double d3=l3.getlength(); double d4=l4.getlength(); double d5=l5.getlength(); double p1=(d1+d2+d5)/2; double p2=(d5+d3+d4)/2; double s1=Math.sqrt(p1*(p1-d1)*(p1-d2)*(p1-d5)); double s2=Math.sqrt(p2*(p2-d5)*(p2-d3)*(p2-d4)); return s1+s2; } /*看四个点能否构成三角形*/ public boolean CanBeTriangle() { Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,y,m); Triangle t3=new Triangle(m,y,z); Triangle t4=new Triangle(x,m,z); if(t1.isOnTheEdge(m)||t2.isOnTheEdge(z)||t3.isOnTheEdge(x)||t4.isOnTheEdge(y)) { return true; } else { return false; } } //判断点是否在四边形内部 public boolean insibx(Point_ p) { boolean f=false; if((jisuan.chac(x,y,p)&&jisuan.chac(y,z,p)&&jisuan.chac(z,m,p)&&jisuan.chac(m,x,p)) ||(!jisuan.chac(x,y,p)&&!jisuan.chac(y,z,p)&&!jisuan.chac(z,m,p)&&!jisuan.chac(m,x,p))) f=true; else f=false; return f; } public int TetragonPoint(Point_ m) {//返回0,-1,1分别对应在四边形上,四边形外,四边形内 if(isOnTetragon(m)) { return 0; } else if(insibx(m)) { return 1; } else { return -1; } } public boolean isOnTetragon(Point_ p) {//点在四边形上 Line line=new Line(); Line[] line4=line.getFourSideline(x,y,z,m); if(line4[0].isOnline(p)||line4[1].isOnline(p)||line4[2].isOnline(p)||line4[3].isOnline(p)) { return true; } else { return false; } } } class wubianx { private Point_ a1; private Point_ a2; private Point_ a3; private Point_ a4; private Point_ a5; public wubianx(Point_ a1, Point_ a2, Point_ a3, Point_ a4, Point_ a5) { this.a1 = a1; this.a2 = a2; this.a3 = a3; this.a4 = a4; this.a5 = a5; } //判断是否构成五边形 public boolean is_wu() { Line l1 = new Line(a1, a2);//12 Line l2 = new Line(a2, a3);//23 Line l3 = new Line(a3, a4);//34 Line l4 = new Line(a4, a5);//45 Line l5 = new Line(a5, a1);//51 boolean f = false; boolean a, b; if ((a1.x == a2.x && a2.x == a3.x) || (a1.x == a2.x && a2.x == a4.x) || (a1.x == a2.x && a2.x == a5.x) || (a1.x == a3.x && a2.x == a4.x) || (a1.x == a3.x && a2.x == a5.x) || (a2.x == a3.x && a3.x == a4.x) || (a2.x == a3.x && a3.x == a5.x) || (a2.x == a4.x && a4.x == a5.x) || (a3.x == a4.x && a4.x == a5.x) || a1.equals(a2) || a1.equals(a3) || a1.equals(a4) || a1.equals(a5) || a2.equals(a3) || a2.equals(a4) || a2.equals(a5) || a3.equals(a4) || a3.equals(a5) || a4.equals(a5)) a = false; else a = true; if (l1.pingxing(l2) || l2.pingxing(l3) || l3.pingxing(l4) || l4.pingxing(l5) || l5.pingxing(l1)) b = false; else b = true; if (a && b) f = true; else f = false; return f; } /* 假设当前连续的三个顶点分别是P1,P2,P3。计算向量P1P2,P2P3的叉乘,如果结果符号一致,则多边形时凸多边形。 */ //判断凹凸五边形 public boolean chac(Point_ a1, Point_ a2, Point_ a3) {//叉乘 double t1 = a2.x - a1.x; double t2 = a2.y - a1.y;//a12 double b1 = a3.x - a2.x; double b2 = a3.y - a3.y;//a23 if ((t1 * b2 - t2 * b1) > 0) return true; else return false; } public boolean aotu() { boolean f = false; if ((chac(a1, a2, a3) && chac(a2, a3, a4) && chac(a3, a4, a5) && chac(a4, a5, a1) && chac(a5, a1, a2)) || (!chac(a1, a2, a3) && !chac(a2, a3, a4) && !chac(a3, a4, a5) && !chac(a4, a5, a1) && !chac(a5, a1, a2))) return true; else return false; } //五边形的周长 public double zc() { double d1, d2, d3, d4, d5; d1 = a1.distance(a2); d2 = a2.distance(a3); d3 = a3.distance(a4); d4 = a4.distance(a5); d5 = a5.distance(a1); double d; d = d1 + d2 + d3 + d4 + d5; return d; } //sqrt(p*(p-d1)(p-d2)(p-d3)用海伦公式计算五边形的面积 public double mianjji() { double d1, d2, d3, d4, d5, d6, d7; d1 = a1.distance(a2); d2 = a2.distance(a3); d3 = a1.distance(a3); d4 = a3.distance(a4); d5 = a1.distance(a4); d6 = a4.distance(a5); d7 = a5.distance(a1); double p1 = (d1 + d2 + d3) / 2; double p2 = (d5 + d3 + d4) / 2; double p3 = (d5 + d6 + d7) / 2; double s1 = Math.sqrt(p1 * (p1 - d1) * (p1 - d2) * (p1 - d3)); double s2 = Math.sqrt(p2 * (p2 - d3) * (p2 - d4) * (p2 - d5)); double s3 = Math.sqrt(p3 * (p3 - d6) * (p3 - d7) * (p3 - d5)); double S; S = s1 + s2 + s3; return S; } //获取五个点相邻两边重合的去除公共点的点的集合 public ArrayList<Point_> getSideCoincidePoint() { ArrayList<Point_> point = new ArrayList<Point_>(); point.add(a1); point.add(a2); point.add(a3); point.add(a4); point.add(a5); Line line0 = new Line(a1, a2);//12 Line line1 = new Line(a2, a3);//23 Line line2 = new Line(a3, a4);//34 Line line3 = new Line(a4, a5);//45 Line line4 = new Line(a5, a1);//51 if (line0.isCoincide(line1)) { point.remove(1); } if (line1.isCoincide(line2)) { if (point.size() == 4) { point.remove(1); } if (point.size() == 5) { point.remove(2); } } if (line2.isCoincide(line3)) { if (point.size() == 3) { point.remove(1); } if (point.size() == 4) { point.remove(2); } if (point.size() == 5) { point.remove(3); } } if (line3.isCoincide(line4)) { if (point.size() == 2) { point.remove(1); } if (point.size() == 3) { point.remove(2); } if (point.size() == 4) { point.remove(3); } if (point.size() == 5) { point.remove(4); } } if (line4.isCoincide(line0)) { point.remove(0); } return point; } //判断五个点是否能构成多边形 public boolean CanBePolygon() { if (getSideCoincidePoint().size() < 3) { return false; } else { return true; } } //判断是否一条直线与多边形有边重合 public boolean haveCoincideSide(Line l) { Line line0 = new Line(a1, a2);//12 Line line1 = new Line(a2, a3);//23 Line line2 = new Line(a3, a4);//34 Line line3 = new Line(a4, a5);//45 Line line4 = new Line(a5, a1);//51 if (l.isCoincide(line0) || l.isCoincide(line1) || l.isCoincide(line2) || l.isCoincide(line3) || l.isCoincide(line4)) { return true; } else { return false; } } //交点是否在多边形的顶点上 public boolean isOnTopPoint(Point_ p) { if (p.equals(a1) || p.equals(a2) || p.equals(a3) || p.equals(a4) || p.equals(a5)) { return true; } else { return false; } } //获取交点 public ArrayList<Point_> getjiaod(Line l) { Line line0 = new Line(a1, a2);//12 Line line1 = new Line(a2, a3);//23 Line line2 = new Line(a3, a4);//34 Line line3 = new Line(a4, a5);//45 Line line4 = new Line(a5, a1);//51 ArrayList<Point_> point = new ArrayList<Point_>();//存交点 if(l.getIntersection(line0)!=null) { if(l.isBetween(l.getIntersection(line0))||isOnTopPoint(l.getIntersection(line0))) { point.add(l.getIntersection(line0)); } } if(l.getIntersection(line1)!=null) { if(l.isBetween(l.getIntersection(line1))||isOnTopPoint(l.getIntersection(line1))) { point.add(l.getIntersection(line1)); } } if(l.getIntersection(line2)!=null) { if(l.isBetween(l.getIntersection(line2))||isOnTopPoint(l.getIntersection(line2))) { point.add(l.getIntersection(line2)); } } if(l.getIntersection(line3)!=null) { if(l.isBetween(l.getIntersection(line3))||isOnTopPoint(l.getIntersection(line3))) { point.add(l.getIntersection(line3)); } } if(l.getIntersection(line4)!=null) { if(l.isBetween(l.getIntersection(line4))||isOnTopPoint(l.getIntersection(line4))) { point.add(l.getIntersection(line4)); } } LinkedHashSet<Point_> set = new LinkedHashSet<Point_>(point); ArrayList<Point_> points = new ArrayList<Point_>(set); return points; } //直线将多边形分割,将在直线左侧的点存入数组1 public ArrayList<Point_> getLeftPoint(Line l) { ArrayList<Point_> pointnew = new ArrayList<Point_>(); ArrayList<Point_> point = getSideCoincidePoint(); for (int i = 0; i < point.size(); i++) { if (point.get(i).LeftOfLine(l) == 1) { pointnew.add(point.get(i)); } } return pointnew; } //直线将多边形分割,将在直线右侧的点存入数组1 public ArrayList<Point_> getRightPoint(Line l) { ArrayList<Point_> pointnew = new ArrayList<Point_>(); ArrayList<Point_> point = getSideCoincidePoint(); for (int i = 0; i < point.size(); i++) { if (point.get(i).LeftOfLine(l) == 1) { pointnew.add(point.get(i)); } } return pointnew; } //切割五边形,计算面积 public double getcutwubianx(Line l) { Point_ p1 = getjiaod(l).get(0);//直线与多边形的两个交点 Point_ p2 = getjiaod(l).get(1); double S = 0; if (getLeftPoint(l).size() == 1 || getRightPoint(l).size() == 1) { if (getLeftPoint(l).size() == 1) { Triangle t = new Triangle(getLeftPoint(l).get(0), p1, p2); S = t.mji(); } if (getRightPoint(l).size() == 1) { Triangle t = new Triangle(getRightPoint(l).get(0), p1, p2); S = t.mji(); } } else if (getLeftPoint(l).size() == 2 && getRightPoint(l).size() == 2) { sibianx t1=new sibianx(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); sibianx t2=new sibianx(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { S=t1.mj(); }else S=t2.mj(); }else { if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==3) { sibianx t1=new sibianx(p1,p2,getLeftPoint(l).get(0),getLeftPoint(l).get(1)); sibianx t2=new sibianx(p1,p2,getLeftPoint(l).get(1),getLeftPoint(l).get(0)); if(t1.CanBeTriangle()) { S=t1.mj(); } else { S=t2.mj(); } }else { sibianx t1=new sibianx(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); sibianx t2=new sibianx(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { S=t1.mj(); } else { S=t2.mj(); } } } return S; } //切割四边形,计算面积 public double getcutsibianx(Line l){ Point_ p1 = getjiaod(l).get(0);//直线与多边形的两个交点 Point_ p2 = getjiaod(l).get(1); double S = 0; if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==3) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); S=t.mji(); } if(getLeftPoint(l).size()==3&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); S=t.mji(); } if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==2) { sibianx t1=new sibianx(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); sibianx t2=new sibianx(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { S=t1.mj(); } else { S=t2.mj(); } } if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); S=t.mji(); } return S; } //切割三角形,并获取其中之一的切割面积 public double getCutTriangle(Line l) { double s = 0; Point_ p1 = getjiaod(l).get(0);//直线与多边形的两个交点 Point_ p2 = getjiaod(l).get(1); if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==2) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); s=t.mji(); } if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.mji(); } if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.mji(); } return s; } //如果切割的交点为2,分别计算两个面积并比较大小输出 public void InputTwoArea(Line l) { if(getjiaod(l).size()==2) { double s1,s2; if(is_wu()) { s1=getcutwubianx(l); s2=mianjji()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } if(getSideCoincidePoint().size()==4) { s1=getcutsibianx(l); sibianx t=new sibianx(getSideCoincidePoint().get(0),getSideCoincidePoint().get(1),getSideCoincidePoint().get(2),getSideCoincidePoint().get(3)); s2=t.mj()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } if(getSideCoincidePoint().size()==3) { s1=getCutTriangle(l); Triangle t=new Triangle(getSideCoincidePoint().get(0),getSideCoincidePoint().get(1),getSideCoincidePoint().get(2)); s2=t.mji()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } } else { System.out.println(getjiaod(l).size()); } } //判断一个点是否在五个点构成的多边形的内部 public boolean inwu(Point_ p) { boolean f=false; if((jisuan.chac(a1,a2,p)&&jisuan.chac(a2,a3,p)&&jisuan.chac(a3,a4,p)&&jisuan.chac(a4,a5,p)&&jisuan.chac(a5,a1,p)) ||(!jisuan.chac(a1,a2,p)&&!jisuan.chac(a2,a3,p)&&!jisuan.chac(a3,a4,p)&&!jisuan.chac(a4,a5,p)&&!jisuan.chac(a5,a1,p))) f=true; else f=false; return f; } //判断一个点是否在边上 public boolean ontheside(Point_ p) { boolean a=false; Line line0 = new Line(a1, a2);//12 Line line1 = new Line(a2, a3);//23 Line line2 = new Line(a3, a4);//34 Line line3 = new Line(a4, a5);//45 Line line4 = new Line(a5, a1);//51 if(line0.isOnline(p)||line1.isOnline(p)||line2.isOnline(p)||line3.isOnline(p)||line4.isOnline(p)) a=true; else a=false; return a; } //判断点与五边形分离 public boolean liwubx(Point_ p) { if(!inwu(p)&&!ontheside(p)&&!isOnTopPoint(p)) return true; else return false; } public boolean chongh(wubianx w) { Line line0 = new Line(w.a1, w.a2);//12 Line line1 = new Line(w.a2, w.a3);//23 Line line2 = new Line(w.a3, w.a4);//34 Line line3 = new Line(w.a4, w.a5);//45 Line line4 = new Line(w.a5, w.a1);//51 if(haveCoincideSide(line0)&&haveCoincideSide(line1)&&haveCoincideSide(line2)&&haveCoincideSide(line3)&&haveCoincideSide(line4)) { return true; }else return false; } //判断两个五边形的关系 public void gxi(wubianx w) { Line line0 = new Line(w.a1, w.a2);//12 Line line1 = new Line(w.a2, w.a3);//23 Line line2 = new Line(w.a3, w.a4);//34 Line line3 = new Line(w.a4, w.a5);//45 Line line4 = new Line(w.a5, w.a1);//51 //重合 if(haveCoincideSide(line0)&&haveCoincideSide(line1)&&haveCoincideSide(line2)&&haveCoincideSide(line3)&&haveCoincideSide(line4)) { System.out.println("the previous pentagon coincides with the following pentagon"); }else if(inwu(w.a1)&&inwu(w.a2)&&inwu(w.a3)&&inwu(w.a4)&&inwu(w.a5))//包含 { System.out.println("the previous pentagon contains the following pentagon"); }else if(w.inwu(this.a1)&&w.inwu(this.a2)&&w.inwu(this.a3)&&w.inwu(this.a4)&&w.inwu(this.a5))//被包含 { System.out.println("the previous pentagon is inside the following pentagon"); }else if(liwubx(w.a1)&&liwubx(w.a2)&&liwubx(w.a3)&&liwubx(w.a4)&&liwubx(w.a5))//分离 { System.out.println("no overlapping area between the previous pentagon and the following pentagon"); }else if(getjiaod(line0).size()!=0||getjiaod(line1).size()!=0||getjiaod(line2).size()!=0||getjiaod(line3).size()!=0||getjiaod(line4).size()!=0) { System.out.println("the previous pentagon is interlaced with the following pentagon"); }else{ System.out.println("the previous pentagon is connected to the following pentagon"); } } //判断五边形与四边形的关系 public void ws(Point_ x,Point_ y,Point_ z,Point_ m) { Line line0 = new Line(x, y);//12 Line line1 = new Line(y, z);//23 Line line2 = new Line(z, m);//34 Line line3 = new Line(m, x);//41 if(inwu(m)&&inwu(x)&&inwu(y)&&inwu(z)) { System.out.println("the previous pentagon contains the following quadrilateral"); }else if(getjiaod(line0).size()!=0||getjiaod(line1).size()!=0||getjiaod(line2).size()!=0||getjiaod(line3).size()!=0) { System.out.println("the previous pentagon is interlaced with the following quadrilateral"); } } } class jisuan{ public static boolean chac(Point_ a, Point_ b, Point_ p){ double tx= b.x-a.x; double ty=b.y-a.y; double hx=p.x-a.x; double hy=p.y-a.y; if(tx*hy-hx*ty<0) return true; else return false; } } class guanxi{ public static int xz(wubianx w)//判断形状 { int a=0; ArrayList<Point_> point= w.getSideCoincidePoint(); if(w.CanBePolygon()) { if(point.size()==3) a=1;//三角形 if(point.size()==4) a=2;//四边形 if(point.size()==5) a=3;//五边形 } return a; } public static void gx(wubianx w, wubianx z) { int a,b; a=xz(w); b=xz(w); ArrayList<Point_> p1=w.getSideCoincidePoint(); ArrayList<Point_> p2=z.getSideCoincidePoint(); if(a==3&&b==3) { w.gxi(z); }else if(a==3&&b==2) { w.ws(p2.get(0),p2.get(1),p2.get(2),p2.get(3)); }else if(a==2&&b==3) { System.out.println("the previous quadrilateral coincides with the following pentagon"); } } public static void dian(Point_ p,wubianx w) { if(w.CanBePolygon()) { int a=0; a=xz(w); ArrayList<Point_> point= w.getSideCoincidePoint(); if(a==1) { Triangle t =new Triangle(point.get(0),point.get(1),point.get(2)); int b=0; b=t.TrianglePoint(p); if(b==0) System.out.println("on the triangle"); else if(b==1) System.out.println("in the triangle"); else if(b==-1) System.out.println("outof the triangle"); } if(a==2) { sibianx t1=new sibianx(point.get(0),point.get(1),point.get(2),point.get(3)); int b=0; b=t1.TetragonPoint(p); if(b==0) System.out.println("on the quadrilateral"); else if(b==1) System.out.println("in the quadrilateral"); else if(b==-1) System.out.println("outof the quadrilateral"); } if(a==3) { if(w.inwu(p)) System.out.println("in the pentagon"); else if(w.liwubx(p)) System.out.println("outof the pentagon"); else if ((w.ontheside(p))) System.out.println("on the pentagon"); } } } }View Code
心得:一开始写的时候按照之前写四边形的方法只用了一个Point类,后来发现有点看困难,然后添加了其他几个类。本次计算有很多与四边形计算重复的代码。选项4、5、6写起来有点复杂。对于判断多边形是否为凸多边形,一开始是不大会,然后上网查了资料,叉乘 可以用来判断两个向量在空间中的位置关系,在平面内的多边形,我们有它的有序点集,我们可以知道这三个点的走势,只需要记录叉乘的符号即可,只要有一次叉乘出来的结果符号和之前的不对,就是凹多边形,如果直到最后多是同样的符号,那么就是凸多边形。
然后关于切割面积,判断切割两边是什么形状,首先得去除多余的点,使用了arrylist里面的remove方法,其次将在直线两边的点分别存入两个数组,通过判断两个数组的大小判断左右点的个数,然后就可以判断切割出的形状。
总体来说,这次代码写起来有点困难。
3.期中考试设计与分析
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)
方法。
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner s=new Scanner(System.in); double x1=s.nextDouble(); double y1=s.nextDouble(); double x2=s.nextDouble(); double y2=s.nextDouble(); String color=s.next(); if((x1>0&&x1<=200&&y1>0&&y1<=200)&&(x2>0&&x2<=200&&y2>0&&y2<=200)) { Point point1=new Point(x1,y1); Point point2=new Point(x2,y2); Line line=new Line(point1,point2,color); line.display(); } else { System.out.print("Wrong Format"); } } } class Point{ private double x; private double y; public Point(){ } public Point(double x,double y){ this.x=x; this.y=y; } public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } public void display(){ System.out.printf("(%.2f,%.2f)\n",x,y); } } class Line{ private Point point1; private Point point2; private String color; public Line(){ } public Line(Point point1,Point point2,String color) { this.point1=point1; this.point2=point2; this.color=color; } public Point getPoint1() { return point1; } public Point getPoint2() { return point2; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void setPoint1(Point point1) { this.point1 = point1; } public void setPoint2(Point point2) { this.point2 = point2; } public double getDistance(){ double distance; distance=Math.sqrt(Math.pow((point1.getX()-point2.getX()),2)+Math.pow((point1.getY()-point2.getY()),2)); return distance; } public void display(){ System.out.println("The line's color is:"+color); System.out.println("The line's begin point's Coordinate is:"); point1.display(); System.out.println("The line's end point's Coordinate is:"); point2.display(); System.out.printf("The line's length is:%.2f",getDistance()); } }View Code
根据类图进行编写,不是很难。
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();
源码如下:
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner s=new Scanner(System.in); double x1=s.nextDouble(); double y1=s.nextDouble(); double x2=s.nextDouble(); double y2=s.nextDouble(); String color=s.next(); if((x1>0&&x1<=200&&y1>0&&y1<=200)&&(x2>0&&x2<=200&&y2>0&&y2<=200)) { Point point1=new Point(x1,y1); Point point2=new Point(x2,y2); Line line=new Line(point1,point2,color); Plane plane=new Plane(color); Element a= point1;//起点Point a.display(); Element b = point2;//终点Point b.display(); Element c = line;//线段 c.display(); Element d = plane;//面 d.display(); } else { System.out.print("Wrong Format"); } } } abstract class Element{ public void display(){ } } class Point extends Element{ private double x; private double y; public Point(){ } public Point(double x,double y){ this.x=x; this.y=y; } public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } @Override public void display(){ System.out.printf("(%.2f,%.2f)\n",x,y); } } class Line extends Element{ private Point point1; private Point point2; private String color; public Line(){ } public Line(Point point1,Point point2,String color) { this.point1=point1; this.point2=point2; this.color=color; } public Point getPoint1() { return point1; } public Point getPoint2() { return point2; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void setPoint1(Point point1) { this.point1 = point1; } public void setPoint2(Point point2) { this.point2 = point2; } public double getDistance(){ double distance; distance=Math.sqrt(Math.pow((point1.getX()-point2.getX()),2)+Math.pow((point1.getY()-point2.getY()),2)); return distance; } @Override public void display(){ System.out.println("The line's color is:"+color); System.out.println("The line's begin point's Coordinate is:"); point1.display(); System.out.println("The line's end point's Coordinate is:"); point2.display(); System.out.printf("The line's length is:%.2f\n",getDistance()); } } class Plane extends Element{ private String color; public Plane(){ } public Plane(String color) { this.color=color; } public void setColor(String color) { this.color = color; } public String getColor() { return color; } @Override public void display() { super.display(); System.out.println("The Plane's color is:"+color); } }View Code
类图如下
心得:主要是对抽象类的继承,使用abstract实现设计一个抽象父类
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:输入结束
输入结束后,按容器中的对象顺序分别调用每个对象的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(); }
display()
方法进行输出。
源码如下:
import java.util.ArrayList; import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner s = new Scanner(System.in); GeometryObject p = new GeometryObject(); int choice = s.nextInt(); while (choice != 0) { switch (choice) { case 1://insert Point object into list double x = s.nextDouble(); double y = s.nextDouble(); if (x > 0 && x <= 200 && y > 0 && y <= 200) { Point point = new Point(x, y); p.add(point); } else { System.out.print("Wrong Format"); } break; case 2://insert Line object into list double x1 = s.nextDouble(); double y1 = s.nextDouble(); double x2 = s.nextDouble(); double y2 = s.nextDouble(); if ((x1 > 0 && x1 <= 200 && y1 > 0 && y1 <= 200) && (x2 > 0 && x2 <= 200 && y2 > 0 && y2 <= 200)) { Point point1=new Point(x1,y1); Point point2=new Point(x2,y2); String color = s.next(); Line line=new Line(point1,point2,color); p.add(line); } else { System.out.print("Wrong Format"); } break; case 3://insert Plane object into list String color1 = s.next(); Plane plane=new Plane(color1); p.add(plane); break; case 4://delete index - 1 object from list int index = s.nextInt(); ArrayList<Element> l=new ArrayList<>(); l=p.getList(); if(index>=1&&index<l.size()+1) p.remove(index-1); } choice = s.nextInt(); } ArrayList<Element> list=new ArrayList<>(); list=p.getList(); for ( Element i : list) { i.display(); } } } abstract class Element{ public void display(){ } } class Point extends Element{ private double x; private double y; public Point(){ } public Point(double x,double y){ this.x=x; this.y=y; } public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } @Override public void display(){ System.out.printf("(%.2f,%.2f)\n",x,y); } } class Line extends Element{ private Point point1; private Point point2; private String color; public Line(){ } public Line(Point point1,Point point2,String color) { this.point1=point1; this.point2=point2; this.color=color; } public Point getPoint1() { return point1; } public Point getPoint2() { return point2; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void setPoint1(Point point1) { this.point1 = point1; } public void setPoint2(Point point2) { this.point2 = point2; } public double getDistance(){ double distance; distance=Math.sqrt(Math.pow((point1.getX()-point2.getX()),2)+Math.pow((point1.getY()-point2.getY()),2)); return distance; } @Override public void display(){ System.out.println("The line's color is:"+color); System.out.println("The line's begin point's Coordinate is:"); point1.display(); System.out.println("The line's end point's Coordinate is:"); point2.display(); System.out.printf("The line's length is:%.2f\n",getDistance()); } } class Plane extends Element{ private String color; public Plane(){ } public Plane(String color) { this.color=color; } public void setColor(String color) { this.color = color; } public String getColor() { return color; } @Override public void display() { super.display(); System.out.println("The Plane's color is:"+color); } } class GeometryObject{ private ArrayList<Element> list=new ArrayList<>(); public GeometryObject(){ } public void add(Element element){ list.add(element); } public void remove(int index){ list.remove(index); } public ArrayList<Element> getList() { return list; } }View Code
类图如下
心得:用ArrayList<Element>
类型写一个对象,将point,line放进这个容器,主要是利用这个函数。
三、总结
通过几次的多边形计算,学会了用叉乘的方法判断图形的凹凸形以及图形的一些基本计算;这几次的练习学会了使用ArrayList操作多个对象,并使用其中的各类方法,并学习了正则表达式,利用正则表达式简化格式问题。学会了使用继承和多态简化重复的代码。
标签:return,Point,期中考试,double,Blog2,pta,new,Line,public From: https://www.cnblogs.com/jiang-jq12/p/16830461.html