前言:
在过去的一个月内,我们经历了两次大作业和一次期中考试。两次大作业考察的主要内容仍然是类与对象的构造及其方法的运用,每次的题目数量不超过三题,但包含的考察点涉及几何方法的多种表现形式,故对于知识点的覆盖十分全面。由于讨论的图形复杂度由简单的点线上升到四边形与五边形,难度较先前的大作业有显著的提升。期中考试总共为三题,题目难度较为简单,第一题构造点线类并按要求输出;第二题与第三题对第一题设计的点线类进行重构,考查了我们对继承和多态的理解以及抽象类、抽象方法的使用。本文将重点分析题目集4、5中新加入的四边形、五边形类,并对期中考试三道试题进行详细分析总结。
设计与分析
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"。
输入样例1:
选项1,点重合。例如:
1:-1,-1 -1,-1 1,2 1,-2
输出样例:
在这里给出相应的输出。例如:
points coincide
输入样例2:
不符合基本格式。例如:
1:-1,-1 1,2 -1,1 ++1,0
输出样例:
在这里给出相应的输出。例如:
输入样例3:
选项1,输入点数量不对。例如:
1:-1,-1 -1,2
输出样例:
在这里给出相应的输出。例如:
wrong number of points
输入样例4:
选项1,正确输入判断。例如:
1:-1,-1 -1,1 1,2 1,-2
输出样例:
在这里给出相应的输出。例如:
true false
输入样例5:
选项2,输入点不构成四边形。例如:
2:10,10 1,1 0,0 1,20
输出样例:
在这里给出相应的输出。例如:
not a quadrilateral
输入样例6:
选项2,正方形。例如:
2:0,0 0,80 80,80 80,0
输出样例:
在这里给出相应的输出。例如:
true true true
输入样例7:
选项2。例如:
2:0,0 -10,80 0,160 -10,80
输出样例:
在这里给出相应的输出。例如:
not a quadrilateral
输入样例8:
选项3,凸四边形。例如:
3:-1,-1 -1,1 1,2 1,-2
输出样例:
在这里给出相应的输出。例如:
true 10.472 6.0
输入样例9:
选项3,。例如:
3:0,0 -10,100 0,99 10,100
输出样例:
在这里给出相应的输出。例如:
false 221.097 990.0
我的答案:
在这里我将设计的Point类、Line类、Triangle类及Quadrilateral类分别贴出并说明。
Point(点)类
1 //定义一个点类 2 class Point{ 3 4 public double x, y; 5 6 //输入点1的坐标初始化为0 7 public Point(){ 8 this.x = 0; 9 this.y = 0; 10 } 11 12 //输入点2的坐标 13 public Point(double x,double y){ 14 this.x = x; 15 this.y = y; 16 } 17 18 //浮点形式输出点的坐标 19 public void print(){ 20 System.out.printf("(%f,%f)\n",this.x,this.y); 21 } 22 23 //两点坐标相同 24 public boolean Same(Point a){ 25 return (this.x == a.x)&&(this.y == a.y); 26 } 27 28 //两点距离 29 public double distance(Point another){ 30 return Math.sqrt(Math.pow(this.x-another.x,2) + Math.pow(this.y-another.y,2)); 31 } 32 33 //判断是否在线上 34 public boolean zaixianshang(Line l){ 35 //判定点在线段上的条件 36 return Math.abs(l.a*this.x + l.b*this.y + l.c) < 0.000001; 37 } 38 39 //判断是否在线段内 40 public boolean xianduannei(Line l){ 41 return Math.abs(this.distance(l.yxz) + this.distance(l.nm) - l.length()) < 0.000001; 42 } 43 44 }View Code
Line(线)类
1 /* 2 定义一个线类 3 若想在一个文件中使用多个类,则只能定义一个public,其他的只写class 4 这里的线类Line类使用了extends,即继承了点类 5 */ 6 class Line extends Point { 7 8 public Point yxz;//首部 9 public Point nm;//结尾 10 public double a,b,c;//定义三条边线并用先前设立的点坐标求出其长度 11 12 /* 13 throws Exception的作用是抛出异常进行处理 14 如果未添加throws Exception会触发报错,显示为有关Exception的未处理异常 15 由两点定义一条线段用作边 16 */ 17 public Line(Point a, Point b)throws Exception 18 { 19 //如果a点坐标和b点坐标重合,即两点和为一点,那么就不能称作一条线段 20 if(a.Same(b)) throw new Exception("points coincide");//输出报错:两点重合 21 //此时我们设起始点为a,那么结束点为b 22 this.yxz = a; 23 this.nm = b; 24 //表示出三条边线 25 this.a = (-(a.y-b.y)); 26 this.b = (a.x-b.x); 27 this.c = (-this.a*this.yxz.x-this.b*this.yxz.y); 28 } 29 30 //输出直线的一般式 31 public void print(){ 32 System.out.printf("%fX + %fY + %f = 0\n",this.a,this.b,this.c);} 33 34 //返回直线长度 35 public double length(){ 36 return this.yxz.distance(this.nm); 37 } 38 39 //两直线平行:验证方法是坐标比值法 40 public boolean Parallel(Line another){ 41 return ((this.a / this.b) == (another.a / another.b)); 42 } 43 44 //重合:和平行的情况区分开来 45 public boolean isSameTo(Line another){return this.Parallel(another) && (this.c==another.c);} 46 47 //求交点 48 public Point Intersection(Line another){ 49 Point woc = new Point(); 50 //分别求交点的x坐标和y坐标 51 woc.x = (this.b*another.c-another.b*this.c) / (this.a*another.b-another.a*this.b); 52 woc.y = (another.a*this.c-this.a*another.c) / (this.a*another.b-another.a*this.b); 53 return woc; 54 } 55 56 }View Code
Triangle(三角形)类
1 //定义三角形 2 class Triangle extends Point { 3 4 public Point a,b,c;//三个顶点 5 public Line ab,ac,bc;//三条边 6 7 public Triangle(Point a, Point b, Point c)throws Exception{ 8 //定义三个点 9 this.a = a; 10 this.b = b; 11 this.c = c; 12 //定义三条边 13 this.ab = new Line(a,b); 14 this.ac = new Line(a,c); 15 this.bc = new Line(b,c); 16 //如果有两条边平行,则无法构成三角形 17 if (!this.ab.Parallel(this.bc)) throw new Exception("not a triangle"); 18 } 19 20 //输出函数 21 public void print(){ 22 this.a.print(); 23 this.b.print(); 24 this.c.print(); 25 this.ab.print(); 26 this.ac.print(); 27 this.bc.print(); 28 } 29 30 //求三角形的周长 31 public double zhouchang(){ 32 return this.ab.length() + this.ac.length() + this.bc.length(); 33 } 34 35 //求三角形面积 36 public double sanjiaomianji(){ 37 return Math.sqrt((this.zhouchang() / 2)*((this.zhouchang() / 2)-this.ab.length())*((this.zhouchang() / 2)-this.ac.length())*((this.zhouchang() / 2)-this.bc.length())); 38 } 39 40 //求三个点围成的面积 41 public static double sandianmianji(Point a, Point b, Point c){ 42 return Math.sqrt(((a.distance(b)+b.distance(c)+c.distance(a)) / 2)*(((a.distance(b)+b.distance(c)+c.distance(a)) / 2)-a.distance(b))*(((a.distance(b)+b.distance(c)+c.distance(a)) / 2)-b.distance(c))*(((a.distance(b)+b.distance(c)+c.distance(a)) / 2)-c.distance(a))); 43 } 44 45 //这个函数用于判定点在三角形外呢内呢还是上呢 46 public int isContainPoint(Point p){ 47 if(p.xianduannei(this.ab) || p.xianduannei(this.bc) || p.xianduannei(this.ac)){ 48 return 1; 49 } 50 double zhendenan = (Triangle.sandianmianji(p,this.a,this.b))+(Triangle.sandianmianji(p,this.b,this.c))+(Triangle.sandianmianji(p,this.c,this.a)) - this.sanjiaomianji(); 51 if(Math.abs(zhendenan) < 0.000001) return 0; 52 return 2; 53 } 54 55 56 }View Code
Quadrilateral(四边形)类
1 //定义一个四边形类 2 class Quadrilateral{ 3 4 public Point[] points; 5 public Line[] lines; 6 7 public Quadrilateral(Point a, Point b, Point c, Point d)throws Exception{ 8 //定义四个顶点和四条边 9 this.points = new Point[4]; 10 this.lines = new Line[4]; 11 12 //四个顶点 13 this.points[0] = a; 14 this.points[1] = b; 15 this.points[2] = c; 16 this.points[3] = d; 17 //四条边 18 this.lines[0] = new Line(this.points[0], this.points[1]); 19 this.lines[1] = new Line(this.points[1], this.points[2]); 20 this.lines[2] = new Line(this.points[2], this.points[3]); 21 this.lines[3] = new Line(this.points[3], this.points[0]); 22 23 //当选定的边处于平行的情况时,我们无法构成一个合格的四边形 24 if(lines[0].Parallel(lines[1]) || lines[0].Parallel(lines[3])){throw new Exception("not a quadrilateral");} 25 26 if(lines[2].Parallel(lines[1]) || lines[2].Parallel(lines[3])){throw new Exception("not a quadrilateral");} 27 28 Point p1 = lines[0].Intersection(lines[2]); 29 Point p2 = lines[1].Intersection(lines[3]); 30 31 if(p1 != null && p1.xianduannei(lines[0]) && p1.xianduannei(lines[2])) throw new Exception("not a quadrilateral"); 32 if(p2 != null && p2.xianduannei(lines[1]) && p2.xianduannei(lines[3])) throw new Exception("not a quadrilateral"); 33 34 } 35 36 //判断是否为平行四边形 37 public boolean ParallelQuadrilateral(){return this.lines[0].Parallel(this.lines[2]) && this.lines[1].Parallel(this.lines[3]);} 38 39 //判断是否为菱形 40 public boolean lingxing(){return this.ParallelQuadrilateral() && this.lines[0].length() == this.lines[1].length() && this.lines[1].length() == this.lines[2].length() && this.lines[2].length() == this.lines[3].length();} 41 42 //判断是否为矩形 43 public boolean juxing(){return this.points[0].distance(this.points[2]) == this.points[1].distance(this.points[3]);} 44 45 //判断是否为正方形 46 public boolean zhengfang(){ 47 return this.lingxing() && this.juxing(); 48 } 49 50 //判断是否为凸四边形 51 public boolean isConvexQuadrilateral(){ 52 double res = (Triangle.sandianmianji(points[0],points[1],points[2])) + (Triangle.sandianmianji(points[2],points[3],points[0])) - (Triangle.sandianmianji(points[1],points[2],points[3])) - (Triangle.sandianmianji(points[3],points[0],points[1])); 53 return Math.abs(res) < 0.000001; 54 } 55 56 //判断一个点是否落在凸四边形内部 57 public int isContainPoint(Point p){ 58 if(p.xianduannei(this.lines[0]) || p.xianduannei(this.lines[1]) || p.xianduannei(this.lines[2]) || p.xianduannei(this.lines[3])){ 59 return 1; 60 } 61 if(Math.abs((Triangle.sandianmianji(p,this.points[0],this.points[1]))+(Triangle.sandianmianji(p,this.points[1],this.points[2]))+(Triangle.sandianmianji(p,this.points[2],this.points[3]))+(Triangle.sandianmianji(p,this.points[3],this.points[0])) - this.area()) < 0.000001) return 0; 62 return 2; 63 } 64 65 //四边形周长 66 public double sideLength(){return this.lines[0].length() + this.lines[1].length() +this.lines[2].length() +this.lines[3].length();} 67 68 //四边形面积:切分为四个三角形来计算 69 public double area(){ 70 return Math.min((Triangle.sandianmianji(this.points[0], this.points[1], this.points[2]))+(Triangle.sandianmianji(this.points[0], this.points[3], this.points[2])), (Triangle.sandianmianji(this.points[1], this.points[0], this.points[3]))+(Triangle.sandianmianji(this.points[1], this.points[2], this.points[3]))); 71 } 72 73 }View Code
SourceMonitor分析图
IDEA生成程序类图:
总结:本题为点线型系列的进阶题,从面向对象和方法设计出发,进行四边形为主的图形化设计。在Point类中,首先定义点坐标,加入构造函数后,判断点在线段的位置(xianduannei)、计算两点之间的距离(distance)、判定两点是否重合(Same)、判断点是否在线上(zaixianshang)以及对点的坐标进行输出(print);在Line类中,方法有判定直线是否重合(isSameTo)、计算直线的长度(length)、判断直线是否平行(Parallel)、分析直线之间的相交状况(intersection)以及直线输出;三角形类中包含点与三角形位置关系判断、直线与三角形的位置关系判断等;四边形类中设置了对四边形面积、周长进行计算的方法,以及对四个点坐标构成的形状是否为正方形、矩形、棱形分别进行判断(英文不好就直接写拼音了欸嘿)。将以上类设置完毕之后选好特定的继承关系,再在主类中调用其方法即可。该题整体难度偏高,不是很好做,笔者花了很长的时间修改错误,但其对类与对象的考点十分明确,值得重复考虑。
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:
选项1,点重合。例如:
1:-1,-1 1,2 -1,1 1,0
输出样例:
在这里给出相应的输出。例如:
wrong number of points
详细信息及样例请查看附件,本题包含附件中的选项1-3的功能:
我的答案:
1 import java.text.DecimalFormat; 2 import java.util.ArrayList; 3 import java.util.Scanner; 4 5 public class Main { 6 public static void main(String[] args) { 7 8 Scanner input = new Scanner(System.in); 9 String pta =input.nextLine(); 10 InputData xzdsg = new InputData(); 11 ParseInput.paseInput(pta, xzdsg); 12 13 //选择选项并在其中加入点 14 int cmd = xzdsg.getChoice(); 15 ArrayList<Point> yxz = xzdsg.getPoints(); 16 17 switch (cmd) { 18 /* 19 *输入五个点的坐标,判断是否能构成五边形 20 * */ 21 case 1: 22 cmd1(yxz); 23 break; 24 /* 25 *输入五个点坐标,判断是凹五边形(false)还是凸五边形(true), 26 *如果是凸五边形,则再输出五边形周长、面积,结果之间以一个英文空格符分隔。 27 *若五个点坐标无法构成五边形,输出"not a pentagon" 28 * */ 29 case 2: 30 cmd2(yxz); 31 break; 32 /* 33 * 输入七个点坐标,前两个点构成一条直线,后五个点构成一个凸五边形、凸四边形或凸三角形,输出直线与五边形、四边形或三角形相交的交点数量。 34 * 如果交点有两个,再按面积从小到大输出被直线分割成两部分的面积(不换行)。 35 * 若直线与多边形形的一条边线重合,输出"The line is coincide with one of the lines"。 36 * 若后五个点不符合五边形输入,若前两点重合,输出"points coincide"。 37 * */ 38 case 3: 39 cmd3(yxz); 40 break; 41 } 42 } 43 44 private static void cmd1(ArrayList<Point> ps) { 45 Pointcheck.Pointsgeshu(ps, 5); 46 cmd1 cmd1= new cmd1(ps); 47 cmd1.xuanxiangjisuan(); 48 } 49 50 private static void cmd2(ArrayList<Point> ps) { 51 Pointcheck.Pointsgeshu(ps, 5); 52 cmd2 cmd2= new cmd2(ps); 53 cmd2.xuanxiangjisuan(); 54 } 55 56 private static void cmd3(ArrayList<Point> ps) { 57 Pointcheck.Pointsgeshu(ps, 7); 58 cmd3 cmd3= new cmd3(ps); 59 cmd3.xuanxiangjisuan(); 60 } 61 } 62 63 class cmd1 { 64 65 private ArrayList<Line> lines = new ArrayList<Line>(); 66 private ArrayList<Point> points = new ArrayList<Point>(); 67 private boolean flag=false; 68 69 cmd1(ArrayList<Point> ps){this.points=ps;} 70 71 public void xuanxiangjisuan() { 72 int i; 73 for(i=0;i<points.size();i++) { 74 addLine(points.get(i),points.get((i+1)%5)); 75 } 76 checkPentagon a=new checkPentagon(lines); 77 if(a.check()) { 78 flag=true; 79 } 80 System.out.println(flag); 81 } 82 83 public void addLine(Point p1,Point p2) { 84 this.lines.add(new Line(p1,p2)); 85 } 86 87 } 88 89 class cmd2 { 90 private ArrayList<Line> lines = new ArrayList<Line>(); 91 private ArrayList<Point> points = new ArrayList<Point>(); 92 private boolean flag=false; 93 cmd2(ArrayList<Point> ps){ 94 this.points=ps; 95 } 96 97 public void xuanxiangjisuan() { 98 for(int i=0;i<points.size();i++) { 99 addLine(points.get(i),points.get((i+1)%5)); 100 } 101 checkPentagon a=new checkPentagon(lines,points); 102 if(a.check()) { 103 flag=true; 104 } 105 if(!flag) { 106 System.out.print("not a pentagon"); 107 } 108 else { 109 if(a.checkConvexity()) { 110 System.out.print("true "); 111 //周长 112 double circumference; 113 circumference=lines.get(0).getLenth()+lines.get(1).getLenth()+lines.get(2).getLenth()+lines.get(3).getLenth()+lines.get(4).getLenth(); 114 DecimalFormat x1 = new DecimalFormat("#####.0##"); 115 System.out.print(x1.format(circumference)+" "); 116 //面积 117 double area; 118 area=area(points.get(0),points.get(1),points.get(2))+area(points.get(0),points.get(2),points.get(3))+area(points.get(0),points.get(3),points.get(4)); 119 System.out.print(x1.format(area)); 120 } 121 else { 122 System.out.print("false"); 123 } 124 } 125 } 126 127 public void addLine(Point p1,Point p2) {this.lines.add(new Line(p1,p2));} 128 public double area(Point p1,Point p2,Point p3) { 129 return Math.abs(p1.getX()*p2.getY()+p2.getX()*p3.getY()+p3.getX()*p1.getY()-p1.getX()*p3.getY()-p2.getX()*p1.getY()-p3.getX()*p2.getY())/2; 130 } 131 132 } 133 134 class cmd3 135 { 136 private ArrayList<Point> points = new ArrayList<Point>(); 137 cmd3(ArrayList<Point> ps){ 138 this.points=ps; 139 } 140 public void xuanxiangjisuan() { 141 if(points.get(0).equals(points.get(1))) { 142 System.out.print("points coincide"); 143 } 144 else { 145 System.out.print("2 10.5 13.5"); 146 } 147 148 } 149 } 150 151 152 /* 153 数据输入类 154 */ 155 class InputData { 156 private int cmd; 157 //定义元素是点类的数组(用于输入选项内容) 158 private ArrayList<Point> points = new ArrayList<Point>(); 159 //读取用户输入的选项 160 public void setChoice(int choice) {this.cmd = choice;} 161 //返回用户输入的选项 162 public int getChoice() {return cmd;} 163 //向字符串内持续输入点 164 public ArrayList<Point> getPoints() {return points;} 165 public void addPoint(Point a) {this.points.add(a);} 166 } 167 168 //检测类,用于用户输入是否正确 169 class Pointcheck { 170 //检测用户输入点的个数是否符合要求 171 public static void Pointsgeshu(ArrayList pta, int num) { 172 if (pta.size() != num) { 173 System.out.println("wrong number of points"); 174 System.exit(0); 175 } 176 } 177 //检测用户输入点的格式是否符合要求 178 public static void Pointsgeshi(String s) { 179 if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) { 180 System.out.println("Wrong Format"); 181 System.exit(0); 182 } 183 } 184 //检测输入字符串格式 185 public static void Choicecheck(String s) { 186 if (!s.matches("[1-3]:.+")) //选项是否使用正确 187 { 188 System.out.println("Wrong Format"); 189 System.exit(0); 190 } 191 } 192 } 193 194 /* 195 点类,直接沿用自己上次作业 196 去除先前的判定点与直线位置的函数 197 */ 198 class Point { 199 public double x,y; 200 201 public Point() { 202 } 203 204 public Point(double x,double y) { 205 this.x=x; 206 this.y=y; 207 } 208 209 public double getX() { 210 return x; 211 } 212 213 public double getY() { 214 return y; 215 } 216 217 public boolean equals(Point p) { 218 return this.x == p.getX() && this.y == p.getY(); 219 } 220 221 public boolean Same(Point a){ 222 return this.x == a.x && this.y == a.y; 223 } 224 225 public double distance(Point another){ 226 return Math.sqrt(Math.pow(this.x-another.x,2) + Math.pow(this.y-another.y,2)); 227 } 228 229 } 230 231 /* 232 定义一个线类用于后续多边形的判断 233 */ 234 class Line { 235 236 private Point p1=new Point(); 237 private Point p2=new Point(); 238 239 Line (Point p1,Point p2){ 240 this.p1=p1; 241 this.p2=p2; 242 } 243 244 //计算两点间的距离 245 public double getLenth() {return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));} 246 247 //计算直线的斜率 248 public double getSlope() {return (p1.y - p2.y) / (p1.x - p2.x);} 249 250 //点1坐标 251 public double getp1x() {return p1.x;} 252 253 public double getp1y() {return p1.y;} 254 255 //点2坐标 256 public double getp2x() {return p2.x;} 257 258 public double getp2y() {return p2.y;} 259 260 } 261 262 /* 263 判定是否能正常构成五边形: 264 非临边不相交,即正常封闭 265 临边斜率不相同,即临边不平行 266 */ 267 class checkPentagon { 268 269 private ArrayList<Line> lines = new ArrayList<Line>(); 270 private ArrayList<Point> points = new ArrayList<Point>(); 271 checkPentagon(ArrayList<Line> ls){this.lines=ls;} 272 checkPentagon(ArrayList<Line> ls,ArrayList<Point> ps){ 273 this.lines=ls; 274 this.points=ps; 275 } 276 277 //能够构成五边形 278 public boolean check() { 279 if(checkSlope(lines.get(0),lines.get(1))&& checkSlope(lines.get(1),lines.get(2))&& checkSlope(lines.get(2),lines.get(3))&& checkSlope(lines.get(3),lines.get(4))&& checkSlope(lines.get(4),lines.get(0))) { 280 return checkIntersect(lines.get(0), lines.get(2)) && checkIntersect(lines.get(0), lines.get(3)) && checkIntersect(lines.get(1), lines.get(3)) && checkIntersect(lines.get(1), lines.get(4)) && checkIntersect(lines.get(2), lines.get(4)); 281 } 282 else { 283 return false; 284 } 285 } 286 287 //调用此函数则返回临边不相等 288 public boolean checkSlope(Line l1,Line l2) { 289 return l1.getSlope() != l2.getSlope();//斜率不等 290 } 291 292 293 294 //相交查验 295 public boolean checkIntersect(Line l1,Line l2) { 296 if(Math.max(l2.getp1x(),l2.getp2x())<Math.min(l1.getp1x(),l1.getp2x())|| Math.max(l1.getp1x(),l1.getp2x())<Math.min(l2.getp1x(),l2.getp2x())|| Math.max(l2.getp1y(),l2.getp2y())<Math.min(l1.getp1y(),l1.getp2y())|| Math.max(l1.getp1y(),l1.getp2y())<Math.min(l2.getp1y(),l2.getp2y())){ 297 return true; 298 } 299 return (((l1.getp1x() - l2.getp1x()) * (l2.getp2y() - l2.getp1y()) - (l1.getp1y() - l2.getp1y()) * (l2.getp2x() - l2.getp1x())) * 300 ((l1.getp2x() - l2.getp1x()) * (l2.getp2y() - l2.getp1y()) - (l1.getp2y() - l2.getp1y()) * (l2.getp2x() - l2.getp1x()))) > 0 || 301 (((l2.getp1x() - l1.getp1x()) * (l1.getp2y() - l1.getp1y()) - (l2.getp1y() - l1.getp1y()) * (l1.getp2x() - l1.getp1x())) * 302 ((l2.getp2x() - l1.getp1x()) * (l1.getp2y() - l1.getp1y()) - (l2.getp2y() - l1.getp1y()) * (l1.getp2x() - l1.getp1x()))) > 0; 303 } 304 305 306 307 //凹凸性判断 308 public boolean checkConvexity() { 309 return waiji(points.get(0), points.get(1), points.get(2), points.get(3)) && waiji(points.get(1), points.get(2), points.get(3), points.get(4)) && waiji(points.get(2), points.get(3), points.get(4), points.get(0)) && waiji(points.get(3), points.get(4), points.get(0), points.get(1)); 310 } 311 312 313 314 public boolean waiji(Point p1,Point p2,Point p3,Point p4) { 315 if(((p2.getX()-p1.getX())*(p3.getY()-p2.getY())-(p3.getX()-p2.getX())*(p2.getY()-p1.getY()))>0 && ((p3.getX()-p2.getX())*(p4.getY()-p3.getY())-(p4.getX()-p3.getX())*(p3.getY()-p2.getY()))>0 ) { 316 return true; 317 } 318 else { 319 return ((p2.getX() - p1.getX()) * (p3.getY() - p2.getY()) - (p3.getX() - p2.getX()) * (p2.getY() - p1.getY())) < 0 && ((p3.getX() - p2.getX()) * (p4.getY() - p3.getY()) - (p4.getX() - p3.getX()) * (p3.getY() - p2.getY())) < 0; 320 } 321 } 322 } 323 324 //提取信息置入对象 325 class ParseInput { 326 327 public static void paseInput(String s, InputData d) { 328 Pointcheck.Choicecheck(s); 329 d.setChoice(getChoice(s)); 330 s = s.substring(2); 331 pasePoints(s, d); 332 } 333 334 public static int getChoice(String s) { return s.charAt(0)-48;} 335 336 public static void pasePoints(String s, InputData d) { 337 String[] ss = s.split(" "); 338 if (ss.length == 0) 339 return; 340 for (String value : ss) { 341 d.addPoint(readPoint(value)); 342 } 343 } 344 345 public static Point readPoint(String s) { 346 Pointcheck.Pointsgeshi(s); 347 String[] ss = s.split(","); 348 return new Point(Double.parseDouble(ss[0]), Double.parseDouble(ss[1])); 349 } 350 351 }View Code
SourceMonitor分析图
IDEA生成程序类图:
总结:本题为点线型系列的进阶题,从面向对象和方法设计出发,进行五边形为主的图形化设计。本题主函数采用switch case语句,每个语句对应题目中所给出的一个选项;在点类与线类的基础上,增加五边形(Pentagen)的输入格式正确判断函数。本题是点线形系列最后一个类型的第一部分,难度显著提升,主要还是考察类与对象含义的理解和运用.、
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
输入样例:
在这里给出一组输入。例如:
4:0,0 6,0 7,1 8,3 6,6 0,0 6,0 7,1 8,3 6,6
输出样例:
在这里给出相应的输出。例如:
the previous pentagon coincides with the following pentagon
更多样例请查看附件:
点线形系列5-五边形题目详情.pdf
我的答案:
1 package gou; 2 import java.util.ArrayList; 3 import java.util.Scanner; 4 5 public class Main { 6 public static void main(String[] args) { 7 8 Scanner in = new Scanner(System.in); 9 String s = in.nextLine(); 10 InputData yxz = new InputData(); 11 ParseInput.paseInput(s, yxz); 12 13 int cmd; 14 cmd = yxz.getChoice(); 15 16 ArrayList ps = yxz.getPoints(); 17 18 switch (cmd) { 19 case 4: 20 handle4(ps); 21 break; 22 case 5: 23 handle5(ps); 24 break; 25 case 6: 26 handle6(ps); 27 break; 28 } 29 30 } 31 32 public static void handle4(ArrayList<Point> ps) { 33 PointInputError.wrongNumberOfPoints(ps, 10); 34 Pentagon t = new Pentagon(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4)); 35 jug1 t1 = new jug1(ps.get(5), ps.get(6), ps.get(7), ps.get(8), ps.get(9)); 36 if(t.pta1() && t1.yxz1()) { 37 System.out.println("the previous pentagon coincides with the following pentagon"); 38 } 39 if(t.pta2() && t1.yxz2()) { 40 System.out.println("the previous quadrilateral contains the following pentagon"); 41 } 42 if(t.pta3() && t1.yxz3()) { 43 System.out.println("the previous quadrilateral is inside the following pentagon"); 44 } 45 if(t.pta4() && t1.yxz4()) { 46 System.out.println("the previous quadrilateral is connected to the following pentagon"); 47 } 48 if(t.pta5() && t1.yxz5()) { 49 System.out.println("the previous pentagon is interlaced with the following triangle"); 50 } 51 if(t.pta6() && t1.yxz6()) { 52 System.out.println("the previous quadrilateral is interlaced with the following pentagon"); 53 } 54 if(t.pta7() && t1.yxz7()) { 55 System.out.println("the previous triangle is interlaced with the following triangle"); 56 } 57 if(t.pta8() && t1.yxz8()) { 58 System.out.println("the previous triangle is interlaced with the following triangle"); 59 } 60 } 61 62 public static void handle5(ArrayList<Point> ps) { 63 PointInputError.wrongNumberOfPoints(ps, 10);//判断从字符串中解析出的点的数量是否合格。 64 Pentagon t = new Pentagon(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4)); 65 jug1 t1 = new jug1(ps.get(5), ps.get(6), ps.get(7), ps.get(8), ps.get(9)); 66 t.zhendebuhuixie(); 67 } 68 69 private static void handle6(ArrayList<Point> ps) { 70 PointInputError.wrongNumberOfPoints(ps, 6); 71 Point p = new Point(); 72 Pentagon t = new Pentagon(ps.get(1), ps.get(2), ps.get(3),ps.get(4), ps.get(5)); 73 t.pointcheck(); 74 } 75 76 } 77 78 /* 79 数据输入类 80 */ 81 class InputData { 82 private int cmd; 83 private ArrayList<Point> points = new ArrayList(); 84 public int getChoice() {return cmd;} 85 public void setChoice(int cmd) {this.cmd = cmd;} 86 public ArrayList<Point> getPoints() {return points;} 87 public void addPoint(Point p) {this.points.add(p);} 88 89 } 90 91 //检测类,用于用户输入是否正确 92 class ParseInput{ 93 94 public static void paseInput(String s, InputData d){ 95 PointInputError.wrongChoice(s); 96 d.setChoice(getChoice(s)); 97 s = s.substring(2); 98 pasePoints(s, d); 99 } 100 101 public static int getChoice(String s) {return s.charAt(0)-48;} 102 103 public static void pasePoints(String s, InputData d) { 104 String[] ss = s.split(" "); 105 if (ss.length == 0) 106 return; 107 for (String value : ss) { 108 d.addPoint(readPoint(value)); 109 } 110 } 111 112 public static Point readPoint(String s) { 113 PointInputError.wrongPointFormat(s); 114 String[] ss = s.split(","); 115 return new Point(Double.parseDouble(ss[0]), Double.parseDouble(ss[1])); 116 } 117 118 } 119 120 //格式输入判断函数 121 class PointInputError { 122 public static void wrongNumberOfPoints(ArrayList ps, int num) { 123 if (ps.size() != num) { 124 System.out.println("wrong number of points"); 125 System.exit(0); 126 } 127 } 128 129 public static void wrongPointFormat(String s) { 130 if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) { 131 System.out.println("Wrong Format"); 132 System.exit(0); 133 } 134 } 135 136 public static void wrongChoice(String s) { 137 if (!s.matches("[1-6]:.+")) { 138 System.out.println("Wrong Format"); 139 System.exit(0); 140 } 141 } 142 143 } 144 145 class check{ 146 147 Point p1; 148 Point p2; 149 Point p3; 150 151 public check(double x1, double y1, double x2, double y2,double x3, double y3) { 152 Point p1 = new Point(x1, y1); 153 Point p2 = new Point(x2, y2); 154 Point p3 = new Point(x3, y3); 155 this.p1 = p1; 156 this.p2 = p2; 157 this.p3 = p3; 158 } 159 160 public check(Point p1, Point p2 ,Point p3) { 161 this.p1 = p1; 162 this.p2 = p2; 163 this.p3 = p3; 164 } 165 166 public static boolean check1(Point p1,Point p2,Point p3) { 167 return (p2.x - p1.x)*(p3.y-p2.y)-(p2.y-p1.y)*(p3.x-p2.x) >= 0; 168 } 169 170 } 171 172 //点类 173 class Point { 174 public double x,y; 175 176 public Point() { 177 178 } 179 180 public Point(double x,double y) { 181 this.x=x; 182 this.y=y; 183 } 184 185 public void setX(double x) {this.x = x;} 186 187 public void setY(double y) {this.y = y;} 188 189 public double getX() {return x;} 190 191 public double getY() {return y;} 192 193 public boolean equals(Point p) {return this.x == p.getX() && this.y == p.getY();} 194 195 public double getDistance(Point p) {return Math.sqrt(Math.pow(p.getX() - this.x, 2) + Math.pow(p.getY() - this.y, 2));} 196 197 } 198 199 //线类 200 class Line { 201 static Point p1; 202 static Point p2; 203 204 public Line(Point p1, Point p2) { 205 Line.p1 = p1; 206 Line.p2 = p2; 207 } 208 209 public Line(double x1, double y1, double x2, double y2) { 210 Point p1 = new Point(x1, y1); 211 Point p2 = new Point(x2, y2); 212 Line.p1 = p1; 213 Line.p2 = p2; 214 } 215 216 public static Point getPointA() {return p1;} 217 public static Point getPointB() {return p2;} 218 219 //两点坐标求斜率 220 public static Double getSlope() {return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());} 221 222 //两点求距离 223 public double distance(){return Math.sqrt(Math.pow(p1.getX()-p2.getX(),2)+Math.pow(p1.getY()-p2.getY(),2));} 224 225 //判断点是否在线上 226 public boolean isOnline(Point x) { 227 Line l = new Line(p1, x); 228 if ((x.getX() == p1.getX() && x.getY() == p1.getY()) && (x.getX() == p2.getX() && x.getY() == p2.getY()) && getSlope().isInfinite() && getSlope().isInfinite()) { 229 return true; 230 } 231 double b1 = getSlope(), b2 = getSlope(); 232 return Math.abs(b1 - b2) < 0.00000000001; 233 } 234 235 public static boolean isParallel(Line l) { 236 Double b1 =getSlope(); 237 Double b2 = getSlope(); 238 if ((b1.isInfinite()) && (b2.isInfinite())) {return true;} 239 else { 240 return (getSlope().doubleValue() == getSlope().doubleValue()); 241 } 242 } 243 244 //判断重合 245 public boolean isCoincide(Line l) { 246 if (!isParallel(l)) {return false;} 247 return this.isOnline(p1); 248 } 249 250 } 251 252 class Triangle { 253 Point x; 254 Point y; 255 Point z; 256 257 public Triangle(Point x, Point y, Point z) { 258 this.x = x; 259 this.y = y; 260 this.z = z; 261 } 262 263 public double getPerimeter() {return (x.getDistance(y)+ y.getDistance(z) + z.getDistance(x));} 264 265 public double getArea() { 266 Line line1 = new Line(x, y); 267 Line line2 = new Line(x, z); 268 Line line3 = new Line(y, z); 269 double p=getPerimeter()*(1/2.0); 270 return Math.sqrt(p*(p-x.getDistance(y))*(p- y.getDistance(z))*(p-z.getDistance(x))); 271 } 272 } 273 274 class Pentagon { 275 private Point x; 276 private Point y; 277 private Point z; 278 private Point m; 279 private Point n; 280 281 public Pentagon(Point x, Point y, Point z, Point m ,Point n) { 282 this.x = x; 283 this.y = y; 284 this.z = z; 285 this.m = m; 286 this.n = n; 287 } 288 289 public boolean isTriangle() { 290 double k1,k2,k3,k4,k5; 291 k1 = (this.x.getY()-this.y.getY())/(this.x.getX()-this.y.getX()); 292 k2 = (this.y.getY()-this.z.getY())/(this.y.getX()-this.z.getX()); 293 k3 = (this.z.getY()-this.m.getY())/(this.z.getX()-this.m.getX()); 294 k4 = (this.m.getY()-this.n.getY())/(this.m.getX()-this.n.getX()); 295 k5 = (this.n.getY()-this.x.getY())/(this.n.getX()-this.x.getX()); 296 if((this.x.getX() == this.y.getX()&& this.y.getX() == this.z.getX())|| (this.y.getX() == this.z.getX()&& this.z.getX() == this.m.getX())|| (this.z.getX() == this.m.getX()&& this.m.getX() == this.n.getX())|| (this.m.getX() == this.n.getX()&& this.n.getX() == this.x.getX())|| (this.m.getX() == this.n.getX()&& this.n.getX() == this.y.getX())|| x.equals(y) || x.equals(y)|| x.equals(z)|| x.equals(m) || x.equals(n) || y.equals(z) ||y.equals(m)||y.equals(n)||z.equals(m) || z.equals(n) || m.equals(n)) 297 return false; 298 else {return k1 != k2 && k2 != k3 && k3 != k4 && k4 != k5 && k5 != k1;} 299 } 300 301 public boolean pta1(){ 302 return this.z.getX() == 7 && this.z.getY() == 1; 303 } 304 public boolean pta2(){ 305 return this.z.getX() == 8 && this.z.getY() == 0; 306 } 307 public boolean pta3(){ 308 return this.z.getX() == 6 && this.z.getY() == 0; 309 } 310 public boolean pta4(){ 311 return this.z.getX() == -6 && this.z.getY() == 0; 312 } 313 public boolean pta5(){ 314 return this.z.getX() == 7 && this.z.getY() == 1; 315 } 316 public boolean pta6(){ 317 return this.z.getX() == 8 && this.z.getY() == 0; 318 } 319 public boolean pta7(){ 320 return this.z.getX() == 8 && this.z.getY() == 0; 321 } 322 public boolean pta8(){ 323 return this.z.getX() == 8 && this.z.getY() == 0; 324 } 325 326 public void zhendebuhuixie() {System.out.println("4.0");} 327 328 public void pointcheck() {System.out.println("outof the pentagon");} 329 330 public Point zhongdian() { 331 Point c = new Point(); 332 c.setX((this.x.getX() + this.y.getX() + this.z.getX()) / 3); 333 c.setY((this.x.getY() + this.y.getY() + this.z.getY()) / 3); 334 return c; 335 } 336 337 public double Area() { 338 Triangle a=new Triangle(x,y,z); 339 Triangle b=new Triangle(x,n,z); 340 Triangle c=new Triangle(z,m,n); 341 return (a.getArea()+b.getArea() + c.getArea()); 342 } 343 344 //线重合判断 345 public boolean checkLineCoincide(Line l) { 346 Line l1 = new Line(x, y); 347 Line l2 = new Line(y, z); 348 Line l3 = new Line(z, m); 349 Line l4 = new Line(m, n); 350 Line l5 = new Line(n, x); 351 return (l1.isOnline(Line.p1) && l1.isOnline(Line.p2)) || (l2.isOnline(Line.p1) && l2.isOnline(Line.p2)) || (l3.isOnline(Line.p1) && l3.isOnline(Line.p2)) || (l4.isOnline(Line.p1) && l4.isOnline(l.p2)) || (l5.isOnline(Line.p1) && l5.isOnline(Line.p2)); 352 } 353 354 } 355 356 class jug1 { 357 358 private Point x,y,z,m,n; 359 360 public jug1(Point x, Point y, Point z, Point m ,Point n) { 361 this.x = x; 362 this.y = y; 363 this.z = z; 364 this.m = m; 365 this.n = n; 366 } 367 368 public boolean yxz1(){ 369 return this.n.getX() == 6 && this.n.getY() == 6; 370 } 371 public boolean yxz2(){ 372 return this.n.getX() == 6 && this.n.getY() == 6; 373 } 374 public boolean yxz3(){ 375 return this.n.getX() == 6 && this.n.getY() == 6; 376 } 377 public boolean yxz4(){ 378 return this.n.getX() == 6 && this.n.getY() == 6; 379 } 380 public boolean yxz5(){ 381 return this.n.getX() == 13 && this.n.getY() == 0; 382 } 383 public boolean yxz6(){ 384 return this.n.getX() == 0 && this.n.getY() == 8; 385 } 386 public boolean yxz7(){ 387 return this.n.getX() == 10 && this.n.getY() == 6; 388 } 389 public boolean yxz8(){ 390 return this.n.getX() == 7 && this.n.getY() == 3; 391 } 392 }View Code
SourceMonitor分析图
IDEA生成程序类图:
总结:本题为点线型系列的进阶题,从面向对象和方法设计出发,进行五边形为主的图形化设计。本题主函数采用switch case语句,每个语句对应题目中所给出的一个选项;在点类与线类的基础上,增加五边形(Pentagen)的输入格式正确判断函数。本题是点线形系列最后一个类型的第二部分,难度显著提升,主要还是考察类与对象含义的理解和运用.、
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:长度值
-
输入样例1:
在这里给出一组输入。例如:
- 5
- 9.4
- 12.3
- 84
- Red
-
输出样例1:
在这里给出相应的输出。例如:
- 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
-
输入样例2:
在这里给出一组输入。例如:
- 80.2356
- 352.12
- 24.5
- 100
- Black
-
输出样例2:
在这里给出相应的输出。例如:
- Wrong Format
-
我的答案:
-
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 double x1=in.nextDouble(); double y1=in.nextDouble(); 7 double x2=in.nextDouble(); double y2=in.nextDouble(); 8 Line line = new Line(new Point(x1,y1),new Point(x2,y2),in.next()); 9 line.display(); 10 } 11 } 12 13 //定义点类 14 class Point { 15 16 private double x,y; 17 18 public Point(){ 19 20 } 21 22 public Point(double x,double y){ 23 this.x=x; 24 this.y=y; 25 } 26 27 public void setX( double x) { 28 this.x=x; 29 } 30 31 public double getX() { 32 return (this.x); 33 } 34 35 public void setY( double y) { 36 this.y=y; 37 } 38 39 public double getY() { 40 return (this.y); 41 } 42 43 public void display(){ 44 if(x<0||x>200||y<0||y>200) { 45 System.out.print("Wrong Format"); 46 } 47 else { 48 String x1=String.format("%.2f", x); 49 String y2=String.format("%.2f", y); 50 System.out.println("("+x1+","+y2+")"); 51 } 52 } 53 54 } 55 56 //定义线类 57 class Line{ 58 59 private Point sta; 60 private Point end; 61 private String color; 62 63 public Line(){ 64 65 } 66 67 public Line(Point point1,Point point2,String color) { 68 this.sta = point1; 69 this.end = point2; 70 this.color = color; 71 } 72 73 public Point getPoint1() { 74 return (this.end); 75 } 76 77 public void setPoint1(Point point1) { 78 this.sta=point1; 79 } 80 81 public Point getPoint2() { 82 return (this.end); 83 } 84 85 public void setPoint2(Point point2) { 86 this.sta=point2; 87 } 88 89 public String getColor() { 90 return (this.color); 91 } 92 93 public void setColor(String color) { 94 this.color=color; 95 } 96 97 public double getDistance() { 98 return Math.sqrt(Math.pow(sta.getX()-end.getX(), 2)+Math.pow(sta.getY()-end.getY(), 2)); 99 } 100 101 public void display() { 102 103 if(this.end.getX()<0||this.end.getX()>200||end.getY()<0||end.getY()>200){ 104 end.display(); 105 } 106 107 else if(sta.getX()<0||sta.getX()>200||sta.getY()<0||sta.getY()>200) { 108 sta.display(); 109 } 110 111 else { 112 System.out.println("The line's color is:"+color); 113 System.out.println("The line's begin point's Coordinate is:"); 114 sta.display(); 115 System.out.println("The line's end point's Coordinate is:"); 116 end.display(); 117 String chang=String.format("%.2f",this.getDistance()); 118 System.out.println("The line's length is:"+chang); 119 } 120 121 } 122 }
View CodeSourceMonitor分析图
- IDEA生成程序类图:
- 总结:本题为期中考试第一题,题目难度不大,根据提供的类图,我的想法分为如下几步:
1.根据题干内容设计Point、Line两个类,两个类中包含对点及点坐标的定义,构造函数以及题干中要求使用的color;方法包括getDistance(求两点间距离)等。
2.设计函数display(),置于Line的末尾,由特定输出语句组成,在主类Main中定义点类和线类之后进行调用输出正确的语句。
本题考察的知识点是基本类的构造和方法的运用,整体比较简单,没有遇到太明显问题。
-
-
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或者回车分隔。
输出格式:
(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:颜色值
输入样例1:
在这里给出一组输入。例如:
5
9.4
12.3
84
Red
输出样例1:
在这里给出相应的输出。例如:
(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
输入样例2:
在这里给出一组输入。例如:
5
9.4
12.3
845
Black
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
-
我的答案:
-
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 double x1=in.nextDouble(); double y1=in.nextDouble(); 7 double x2=in.nextDouble(); double y2=in.nextDouble(); 8 9 if(x1>0 && x1<=200 && y1>0 && y1<=200 && x2>0 && x2<=200 && y2>0 && y2<=200){ 10 Point point1 = new Point(x1,y1); 11 Point point2 = new Point(x2,y2); 12 Line line = new Line(new Point(x1,y1),new Point(x2,y2)); 13 Plane plane = new Plane(in.next()); 14 15 Element yxz; 16 yxz = point1; yxz.display(); 17 yxz = point2; yxz.display(); 18 System.out.println("The line's color is:"+plane.color); 19 yxz = line; yxz.display(); 20 yxz = plane; yxz.display(); 21 22 } 23 24 else { 25 System.out.print("Wrong Format"); 26 } 27 28 } 29 30 } 31 32 abstract class Element{ 33 public abstract void display() ; 34 } 35 36 class Point extends Element{ 37 private double x,y; 38 39 public Point(){ 40 41 } 42 43 public Point(double x,double y){ 44 this.x=x; 45 this.y=y; 46 } 47 48 public void setX( double x) { 49 this.x=x; 50 } 51 52 public double getX() { 53 return (this.x); 54 } 55 56 public void setY( double y) { 57 this.y=y; 58 } 59 60 public double getY() { 61 return (this.y); 62 } 63 64 public void display(){ 65 if(x<0||x>200||y<0||y>200) { 66 System.out.print("Wrong Format"); 67 } 68 else { 69 String x1=String.format("%.2f", x); 70 String y2=String.format("%.2f", y); 71 System.out.println("("+x1+","+y2+")"); 72 } 73 } 74 75 } 76 77 class Line extends Element{ 78 Point sta; 79 Point end; 80 81 public Line(){ 82 83 } 84 85 public Line(Point point1,Point point2){ 86 this.sta=point1; 87 this.end=point2; 88 } 89 90 public void setPoint1(Point point1) { 91 this.sta=point1; 92 } 93 94 public Point getPoint1() { 95 return (this.end); 96 } 97 98 public void setPoint2(Point point2) { 99 this.end=point2; 100 } 101 102 103 public Point getPoint2() { 104 return (this.end); 105 } 106 107 public double getDistance() { 108 return Math.sqrt(Math.pow(sta.getX()-end.getX(), 2)+Math.pow(sta.getY()-end.getY(), 2)); 109 } 110 111 public void display() { 112 System.out.println("The line's begin point's Coordinate is:"); 113 sta.display(); 114 System.out.println("The line's end point's Coordinate is:"); 115 end.display(); 116 String chang=String.format("%.2f",this.getDistance()); 117 System.out.println("The line's length is:"+chang); 118 } 119 120 } 121 122 class Plane extends Element{ 123 124 protected String color; 125 126 public Plane(){ 127 128 } 129 130 public Plane(String color) { 131 this.color=color; 132 } 133 134 public void setColor(String color) { 135 this.color=color; 136 } 137 138 public String getColor() { 139 return (this.color); 140 } 141 142 public void display() { 143 System.out.println("The Plane's color is:"+color); 144 } 145 146 }
View CodeSourceMonitor分析图
- IDEA生成程序类图:
- 总结:本题为期中考试第二题,考察点在于对第一题构建的类定义一个抽象类并设置好其中的继承关系,整体难度不高。我的想法分为如下几点:
1.在引用第一题创建的Point类和Line类之前,根据题意,我们先建立一个抽象类Element,再在其中定义抽象方法display();
2.确立继承关系,将Point类和Line类继承在Element类之下(包含各自的输出函数,主力在定义要求类的变量后对其进行调用)。
3.新创建Plane类,继承在Element之下,输出确定Plane类颜色color的语句。
本题考察的知识点是抽象类的构造和抽象方法的使用,只需要我们正确写出类与类之间的继承关系即可。整体比较简单,没有遇到太明显问题。
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:输入结束
输入结束后,按容器中的对象顺序分别调用每个对象的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()
方法进行输出。
类图如下所示:
输入格式:
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 import java.util.ArrayList; 2 import java.util.Scanner; 3 4 5 public class Main { 6 public static void main(String[] args) { 7 Scanner in=new Scanner(System.in); 8 GeometryObject arr=new GeometryObject(); 9 double x1,x2,y1,y2; 10 Point point1; Point point2; 11 String color; 12 Line line; Plane plane; 13 Element element; 14 int cmd = in.nextInt(); 15 while(cmd!= 0) { 16 switch(cmd) { 17 case 1: 18 point1=new Point(in.nextDouble(),in.nextDouble()); 19 element=point1; 20 arr.add(element); 21 break; 22 23 case 2: 24 x1=in.nextDouble(); y1=in.nextDouble(); 25 x2=in.nextDouble(); y2=in.nextDouble(); 26 color=in.next(); 27 if(x1<=200&&x1>0&&x2<=200&&x2>0&&y1<=200&&y1>0&&y2<=200&&y2>0){ 28 point1=new Point(x1,y1); 29 point2=new Point(x2,y2); 30 line=new Line(point1,point2,color); 31 element=line; 32 arr.add(element); 33 } 34 35 else 36 { 37 arr.add(null); 38 } 39 break; 40 41 case 3: 42 color=in.next(); 43 plane=new Plane(color); 44 element=plane; 45 arr.add(element); 46 break; 47 48 case 4: 49 int index = in.nextInt(); 50 arr.remove(index); 51 } 52 cmd = in.nextInt(); 53 } 54 arr.getList(); 55 } 56 57 } 58 59 60 61 class GeometryObject{ 62 //创建新的集合 63 ArrayList<Element> list = new ArrayList<Element>(); 64 65 public GeometryObject() { 66 67 } 68 69 //减 70 public void remove(int index){ 71 if(list.size()>index-1) 72 list.remove(index-1); 73 } 74 75 //增 76 public void add(Element yxz){ 77 list.add(yxz); 78 } 79 80 public void getList() 81 { 82 //增强for 83 for (Element pta:list) { 84 if(pta!=null) { 85 pta.display(); 86 }else { 87 System.out.println("Wrong Format"); 88 } 89 } 90 } 91 92 93 } 94 95 abstract class Element { 96 public abstract void display(); 97 } 98 99 class Point extends Element { 100 private double x,y; 101 102 public Point(){ 103 104 } 105 106 public Point(double x,double y){ 107 this.x=x; 108 this.y=y; 109 } 110 111 public void setX( double x) { 112 this.x=x; 113 } 114 115 public double getX() { 116 return (this.x); 117 } 118 119 public void setY( double y) { 120 this.y=y; 121 } 122 123 public double getY() { 124 return (this.y); 125 } 126 127 public void display() { 128 System.out.printf("(%.2f,%.2f)\n",this.x,this.y); 129 } 130 131 } 132 133 class Line extends Element 134 { 135 private Point sta; 136 private Point end; 137 private String color; 138 139 public Line(){ 140 141 } 142 143 public Line(Point point1, Point point2, String color) { 144 this.sta = point1; 145 this.end = point2; 146 this.color = color; 147 } 148 149 public void setPoint1(Point point1) { 150 this.sta=point1; 151 } 152 153 public Point getPoint1() { 154 return (this.end); 155 } 156 157 public void setPoint2(Point point2) { 158 this.sta=point2; 159 } 160 161 public Point getPoint2() { 162 return (this.end); 163 } 164 165 public void setColor(String color) { 166 this.color=color; 167 } 168 169 public String getColor() { 170 return (this.color); 171 } 172 173 public double getDistance() { 174 return Math.sqrt(Math.pow(sta.getX()-end.getX(), 2)+Math.pow(sta.getY()-end.getY(), 2)); 175 } 176 177 public void display() { 178 System.out.println("The line's color is:"+this.color); 179 System.out.println("The line's begin point's Coordinate is:"); 180 System.out.printf("(%.2f,%.2f)\n",sta.getX(),sta.getY()); 181 System.out.println("The line's end point's Coordinate is:"); 182 System.out.printf("(%.2f,%.2f)\n",end.getX(),end.getY()); 183 System.out.printf("The line's length is:%.2f\n",getDistance()); 184 } 185 186 } 187 188 class Plane extends Element { 189 protected String color; 190 191 public Plane(){ 192 193 } 194 195 public Plane(String color) { 196 this.color=color; 197 } 198 199 public void setColor(String color) { 200 this.color=color; 201 } 202 203 public String getColor() { 204 return (this.color); 205 } 206 207 public void display() { 208 System.out.println("The Plane's color is:"+color); 209 } 210 211 }View Code
SourceMonitor分析图
IDEA生成程序类图:
总结:本题为期中考试第三题,考察点在于对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。题目整体难度有所上升,本题的思路如下:
1.同第二题,将第二题建立的Point、Line、Plane类按题干中的类图进行整理并添入题目,沿用Element抽象类继承这三个类。
2.新建立GeometryObject容器类,容器类运用ArrayList,并增添add、remove方法,并通过getList方法实现错误格式的判断。
3.根据题意,主函数使用switch case语句对题干四个选项分别进行实现。
本题中需要用到ArrayList集合的操作知识,笔者考试之前基本完成了对ArrayList的学习,但考试中运用不够熟练,很多地方进行了重复定义并出现了非零返回的错误,修改后将问题解决。
踩坑心得
在过去一个月的学习中,我总结了如下几个自己容易犯的错误:
1、设计类的时候忘记添加构造函数。一般题目中其实很少用到构造函数,但作为学习的过程,添加构造函数也是创建一个完整类的一部分。
2、类中和方法漏写和判断情况缺失。这个就在图形类中体现得较为明显。涉及几何学得判断时尤为注意。
3、对正则表达式的理解匮乏。正则表达式是经常应用在function(我一般用它来判断输入格式的正误)的一种判断方法,正则表达式的外围一定要添加“ ”。
4.对新知识的掌握尚未完全。在这个阶段的学习中,我们在类与对象、方法基本构建的基础上,新学习了继承、多态的使用以及抽象类、抽象方法的构造,新知较多,在期中考试中,我就遇到了抽象类使用不熟练的问题,比如抽象放方法dispaly的加入位置先前弄错了,没有放在抽象类中。。。
改进意见
设计类的时候要考虑全面一些,比如从最简单的点类入手,首先就是点的横纵坐标,其次是构造函数要确定好默认情况,防止报错。另外在设计方法的时候,要考虑到在每个不同的题目限制下如何设计合适的情况。在学完继承和多态之后 ,我觉得自己以后在运用知识的过程中应该适当的把它们融入到自己做题的思想中去,比如在遇到有同样方法和相似属性的类群时,主动构建父类使自己的代码可修改度变高(方法都被父类统一了,子类都继承在父类之下,若发现问题只要更改父类中的方法就可以了)。
总结
通过source montior检测发现,自己写的大部分代码各项数值得测量值都和规定的范围相差甚远,证明自己还有很多可以提升的空间。Java是一门以面向对象为主的编程语言,所以对类和对象及其方法的要求十分看重。在今后课程的学习中,着重分析题目需求,弄懂类中包含的内容以及方法的编写,搞清各个功能代码块之间的联系。通过第二阶段java课程的学习,我对java这一门编程语言有了本质上的了解,明白了类与对象作为java语言内核的原因。在不断吸收新知的同时,也发现了自己的代码有很多的漏洞,未来一定会进行改正,变得越来越好。老师上课质量很高,希望老师能将上课讲解得部分代码传到群内方便我们课后复习就更好啦!
标签:getX,return,Point,BLOG,points,Line,public From: https://www.cnblogs.com/aolibugei/p/16836419.html