前言:三次题目集中前两次的题目较为容易,与C语言相差不大,用面向过程的思维基本可以解决,但第三次的题目需要用面向对象的思维,且目前对java的掌握不太够,所以感觉会有点困难,甚至可以说是难度飙升。第三次的题目开始学会用面向对象的思维解决问题,了解了类、属性、方法之间的关系,发现了面向对象的便利。
设计与分析:
题目集2.7-2:RS232是串口常用的通信协议,在异步通信模式下,串口可以一次发送5~8位数据,收发双方之间没有数据发送时线路维持高电平,相当于接收方持续收到数据“1”(称为空闲位),发送方有数据发送时,会在有效数据(5~8位,具体位数由通信双方提前设置)前加上1位起始位“0”,在有效数据之后加上1位可选的奇偶校验位和1位结束位“1”。请编写程序,模拟串口接收处理程序,注:假定有效数据是8位,奇偶校验位采用奇校验。
本题应将输入的字符串进行拆分,分成11位为一组进行判断,但在此之前需进行判数据不足11位或者输入数据全1没有起始位的非法,再将字符串拆分并进行一组一组的判断。
源代码:
若数据不足11位或者输入数据全1没有起始位非法判断:
if(a.length()<11){ System.out.print("null data"); return; } for(i=0;i<a.length();i++){ if(a.charAt(i)=='0'){ flag=1; break; } } if(flag==0){ System.out.print("null data"); return; }
将数据分成11位一组判断:
int start,va=0,pa=0,num=1,sum; for(start=0;start<a.length()-10;start++){ sum=0; if(a.charAt(start)=='0'){ System.out.print(num+":"); num++; if(a.charAt(start+10)=='0'){//停止位错误 va=1; } else{ va=0; for(i=start+1;i<start+9;i++){ if(a.charAt(i)=='1'){ sum++; } } if(sum%2==0){ if(a.charAt(start+9)=='0'){//校验错误 pa=1; } else pa=0; } else{ if(a.charAt(start+9)=='1'){ pa=1; } else pa=0; } } if(va==0){//停止位正确 if(pa==0){ for(i=start+1;i<start+9;i++){ System.out.print(a.charAt(i)); } System.out.print("\n"); } else{ System.out.println("parity check error"); } } else{ System.out.println("validate error"); } start=start+10; } }
代码分析:
本题相对而言较为容易,对题目的理解也较为简单明了,但使用的条件语句判断太多,导致圈复杂度特别高,且输出语句也多次重复,导致整段代码十分的长,不太清晰。后续应尽量减少使用if条件语句判断,使代码更加简洁明了。
题目集3.7-1:输入两个点的坐标,计算两点之间的距离
本题需创建点类,将点的X、Y坐标设置为点类的属性,将两点间的距离使用一个方法计算。本题还要求我们学会拆分字符串,将点的坐标拆分出来,并对字符串使用正则表达式进行非法判断。
源代码:
点类:
class Dian{ double x,y; public double juli(Dian a){ return Math.sqrt(Math.pow(this.x-a.x,2)+Math.pow(this.y-a.y,2)); } }
对拆分的字符进行非法判断:
public static int hefa(String a){ String pattern = "^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$"; Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(a); if(m.matches()){ return 1; } else{ return 0; } }
主类:
public static void main(String[] args){ Scanner in = new Scanner(System.in); String str = in.nextLine(); Dian a = new Dian(); Dian b = new Dian(); String point[] = str.split(" "); String num[] = null; for(String i:point){ num = i.split(","); for(String j:num){ if(hefa(j)==0){ System.out.print("Wrong Format"); return; } } } if(point.length!=2){ System.out.print("wrong number of points"); return; } num = point[0].split(","); a.x = Double.valueOf(num[0]); a.y = Double.valueOf(num[1]); num = point[1].split(","); b.x = Double.valueOf(num[0]); b.y = Double.valueOf(num[1]); if(a.x==b.x && a.y==b.y){ System.out.print("Wrong Format"); return; } double d = a.juli(b); System.out.print(d); }
代码分析:
本题的结构较简单,只需拆分字符串并使用点类进行距离的计算。因为使用了类,通过创建点类,使程序更加的简洁,因此做题时思路也更加清晰,圈复杂度也不是特别高。总体来看本次点类的创建是十分有效的,并且后续可以继续使用。
题目集3.7-2:用户输入一组选项和数据,进行与直线有关的计算。选项包括:
1:输入两点坐标,计算斜率,若线条垂直于X轴,输出"Slope does not exist"。
2:输入三个点坐标,输出第一个点与另外两点连线的垂直距离。
3:输入三个点坐标,判断三个点是否在一条线上,输出true或者false。
4:输入四个点坐标,判断前两个点所构成的直线与后两点构成的直线是否平行,输出true或者false.
5:输入四个点坐标,计算输出前两个点所构成的直线与后两点构成的直线的交点坐标,x、y坐标之间以英文分隔",",并输出交叉点是否在两条线段之内(不含四个端点)的判断结果(true/false),判断结果与坐标之间以一个英文空格分隔。若两条线平行,没有交叉点,则输出"is parallel lines,have no intersection point"。
本题是线相关,而线是由点来确定的,因此线类需要加入点属性,同时需要将线的斜率也设为线的属性。
源代码:
点类:
class Dian{ double x,y; public double juli(Dian a){ return Math.sqrt(Math.pow(this.x-a.x,2)+Math.pow(this.y-a.y,2)); } }
线类:
class Xian{ Dian a = new Dian(); Dian b = new Dian(); double xl; public double xielv(){ this.xl = (this.a.y-this.b.y)/(this.a.x-this.b.x); return this.xl; } public double chuizhijuli(Dian m){ double d; if(this.a.x==this.b.x){ d=Math.abs(m.x-this.a.x); } else{ d=(Math.abs(m.y-this.xl*m.x-(this.a.y-this.xl*this.a.x))/(Math.sqrt(this.xl*this.xl+1))); } return d; } public int pingxing(Xian l){ if(this.a.x==this.b.x&&l.a.x==l.b.x){ return 1; } else if(l.xl == this.xl){ return 1; } else{ return 0; } } public Dian jiaodian(Xian l){ Dian n = new Dian(); double b1; double b2; if(this.a.x==this.b.x){ b2 = l.a.y - l.xl * l.a.x; n.x = this.a.x; n.y = l.xl * n.x + b2; } else if(l.a.x==l.b.x){ b1 = this.a.y - this.xl * this.a.x; n.x = l.a.x; n.y = this.xl * n.x + b1; } else{ b1 = this.a.y - this.xl * this.a.x; b2 = l.a.y - l.xl * l.a.x; n.x = (b2-b1)/(this.xl-l.xl); n.y = l.xl * n.x + b2; } return n; } public int xianshang(Dian m){ if(this.a.x == this.b.x){ if((m.y >this.a.y && m.y < this.b.y)||(m.y > this.b.y && m.y< this.a.y)) return 1; else return 0; } else{ if((m.x >this.a.x && m.x < this.b.x)||(m.x > this.b.x && m.x< this.a.x)) return 1; else return 0; } } }
第一问:
计算线的斜率:需要分两种情况考虑,一种是垂直X轴斜率无限大,一种是拥有斜率,使用公式计算斜率。
if(point.length!=5){ System.out.print("wrong number of points"); return; } else{ Xian l = new Xian(); l.a.x = Double.valueOf(point[1]); l.a.y = Double.valueOf(point[2]); l.b.x = Double.valueOf(point[3]); l.b.y = Double.valueOf(point[4]); /*System.out.print(l.b.x);*/ if(l.a.x==l.b.x&&l.a.y==l.b.y){ System.out.print("points coincide"); return; } else if(l.a.x==l.b.x){ System.out.print("Slope does not exist"); return; } else{ l.xl = l.xielv(); System.out.print(l.xl); } }
第二问:
点到直线的垂直距离:需要分两种情况分析,斜率不存在时垂直距离即为X坐标差,有斜率时需使用公式进行计算。
if(point.length!=7){ System.out.print("wrong number of points"); return; } else{ Dian m = new Dian(); Xian l = new Xian(); m.x = Double.valueOf(point[1]); m.y = Double.valueOf(point[2]); l.a.x = Double.valueOf(point[3]); l.a.y = Double.valueOf(point[4]); l.b.x = Double.valueOf(point[5]); l.b.y = Double.valueOf(point[6]); l.xl = l.xielv(); if(l.a.x==l.b.x&&l.a.y==l.b.y){ System.out.print("points coincide"); return; } else{ System.out.print(l.chuizhijuli(m)); } }
第三问:
判断三个点是否在同一条线上:将后两个点形成一条直线,只需判断第一个点到此直线的垂直距离是否为零即可。
if(point.length!=7){ System.out.print("wrong number of points"); return; } else{ Dian m = new Dian(); Xian l = new Xian(); m.x = Double.valueOf(point[1]); m.y = Double.valueOf(point[2]); l.a.x = Double.valueOf(point[3]); l.a.y = Double.valueOf(point[4]); l.b.x = Double.valueOf(point[5]); l.b.y = Double.valueOf(point[6]); l.xl = l.xielv(); if(l.a.x==l.b.x&&l.a.y==l.b.y){ System.out.print("points coincide"); return; } else{ if(l.chuizhijuli(m)==0) System.out.print("true"); else System.out.print("false"); } }
第四问:
判断两直线是否平行:需分两种情况考虑,若两直线均无斜率,则平行;若两直线都拥有斜率,则斜率相等即为平行。
if(point.length!=9){ System.out.print("wrong number of points"); return; } else{ Xian l1 = new Xian(); Xian l2 = new Xian(); l1.a.x = Double.valueOf(point[1]); l1.a.y = Double.valueOf(point[2]); l1.b.x = Double.valueOf(point[3]); l1.b.y = Double.valueOf(point[4]); l1.xl = l1.xielv(); l2.a.x = Double.valueOf(point[5]); l2.a.y = Double.valueOf(point[6]); l2.b.x = Double.valueOf(point[7]); l2.b.y = Double.valueOf(point[8]); l2.xl = l2.xielv(); if(l1.a.x==l1.b.x&&l1.a.y==l1.b.y||l2.a.x==l2.b.x&&l2.a.y==l2.b.y){ System.out.print("points coincide"); return; } else{ if(l1.pingxing(l2)==1) System.out.print("true"); else System.out.print("false"); } }
第五问:
求两直线的交点坐标并判断交点是否在两线段上:若两直线平行则无焦点;若交点存在,由于交点必定在两条直线上,故只需判断交点的横坐标或纵坐标是否在两个点的范围内即可。
if(point.length!=9){ System.out.print("wrong number of points"); return; } else{ Xian l1 = new Xian(); Xian l2 = new Xian(); Dian m = new Dian(); l1.a.x = Double.valueOf(point[1]); l1.a.y = Double.valueOf(point[2]); l1.b.x = Double.valueOf(point[3]); l1.b.y = Double.valueOf(point[4]); l1.xl = l1.xielv(); l2.a.x = Double.valueOf(point[5]); l2.a.y = Double.valueOf(point[6]); l2.b.x = Double.valueOf(point[7]); l2.b.y = Double.valueOf(point[8]); l2.xl = l2.xielv(); if(l1.a.x==l1.b.x&&l1.a.y==l1.b.y||l2.a.x==l2.b.x&&l2.a.y==l2.b.y){ System.out.print("points coincide"); return; } else{ if(l1.pingxing(l2)==1){ System.out.print("is parallel lines,have no intersection point"); return; } else{ m = l1.jiaodian(l2); if(l1.xianshang(m) == 1 || l2.xianshang(m) == 1){ System.out.print(m.x + "," + m.y + " true"); } else{ System.out.print(m.x + "," + m.y + " false"); } } } }
代码分析:
由于本题的线类未使用最优方法创建,应使用Ax+By+C=0的表达式进行后续方法的计算,导致圈复杂度较高。同时,判断点是否在线段上时,此方法仅适用于点在直线上的情况,适用范围较为狭窄,后续还需改进。因为使用斜率进行计算,故需分斜率不存在的情况进行讨论分析,需要多个if条件判断,因此圈复杂度较高。
题目集3.7-3:用户输入一组选项和数据,进行与三角形有关的计算。选项包括:
1:输入三个点坐标,判断是否是等腰三角形、等边三角形,判断结果输出true/false,两个结果之间以一个英文空格符分隔。
2:输入三个点坐标,输出周长、面积、重心坐标,三个参数之间以一个英文空格分隔,坐标之间以英文","分隔。
3:输入三个点坐标,输出是钝角、直角还是锐角三角形,依次输出三个判断结果(true/false),以一个英文空格分隔,
4:输入五个点坐标,输出前两个点所在的直线与三个点所构成的三角形相交的交点数量,如果交点有两个,则按面积大小依次输出三角形被直线分割成两部分的面积。若直线与三角形一条线重合,输出"The point is on the edge of the triangle"
5:输入四个点坐标,输出第一个是否在后三个点所构成的三角形的内部(输出in the triangle/outof triangle)。
必须使用射线法,原理:由第一个点往任一方向做一射线,射线与三角形的边的交点(不含点本身)数量如果为1,则在三角形内部。如果交点有两个或0个,则在三角形之外。若点在三角形的某条边上,输出"on the triangle"
本题需另新建三角形类,将三角形的三个顶点设为三角形的属性,并使用点、线类。
源代码:
点类:
class Dian{ double x,y; public double juli(Dian a){ return Math.sqrt(Math.pow(this.x-a.x,2)+Math.pow(this.y-a.y,2)); } }
线类:
class Xian{ Dian a = new Dian(); Dian b = new Dian(); double xl; public double xielv(){ this.xl = (this.a.y-this.b.y)/(this.a.x-this.b.x); return this.xl; } public double chuizhijuli(Dian m){ double d; if(this.a.x==this.b.x){ d=Math.abs(m.x-this.a.x); } else{ d=(Math.abs(m.y-this.xl*m.x-(this.a.y-this.xl*this.a.x))/(Math.sqrt(this.xl*this.xl+1))); } return d; } public int pingxing(Xian l){ if(this.a.x==this.b.x&&l.a.x==l.b.x){ return 1; } else if(l.xl == this.xl){ return 1; } else{ return 0; } } public Dian jiaodian(Xian l){ Dian n = new Dian(); double b1; double b2; if(this.a.x==this.b.x){ b2 = l.a.y - l.xl * l.a.x; n.x = this.a.x; n.y = l.xl * n.x + b2; } else if(l.a.x==l.b.x){ b1 = this.a.y - this.xl * this.a.x; n.x = l.a.x; n.y = this.xl * n.x + b1; } else{ b1 = this.a.y - this.xl * this.a.x; b2 = l.a.y - l.xl * l.a.x; n.x = (b2-b1)/(this.xl-l.xl); n.y = l.xl * n.x + b2; } return n; } public int xianshang(Dian m){ if(this.a.x == this.b.x){ if((m.y >this.a.y && m.y < this.b.y)||(m.y > this.b.y && m.y< this.a.y)) return 1; else return 0; } else{ if((m.x >this.a.x && m.x < this.b.x)||(m.x > this.b.x && m.x< this.a.x)) return 1; else return 0; } } }
三角形类:
class Sanjiaoxing{ Dian a = new Dian(); Dian b = new Dian(); Dian c = new Dian(); double zc; double mj; public static double zhouchang(Sanjiaoxing m){ double l1,l2,l3; l1 = Math.sqrt(Math.pow(m.a.x-m.b.x,2) + Math.pow(m.a.y-m.b.y,2)); l2 = Math.sqrt(Math.pow(m.a.x-m.c.x,2) + Math.pow(m.a.y-m.c.y,2)); l3 = Math.sqrt(Math.pow(m.b.x-m.c.x,2) + Math.pow(m.b.y-m.c.y,2)); m.zc = l1+l2+l3; return m.zc; } public static double mianji(Sanjiaoxing m){ double l1,d; Xian l = new Xian(); l.a = m.a; l.b = m.b; l1 = Math.sqrt(Math.pow(m.a.x-m.b.x,2) + Math.pow(m.a.y-m.b.y,2)); d = l.chuizhijuli(m.c); return l1*d/2; } public static Dian zhongxin(Sanjiaoxing m){ Dian n = new Dian(); n.x = (m.a.x + m.b.x + m.c.x)/3; n.y = (m.a.y + m.b.y + m.c.y)/3; return n; } }
第一问:
判断三角形类型:将三个点形成三条线段,并通过三个线段的长度进行三角形类型的判断。
if(point.length!=7){ System.out.print("wrong number of points"); return; } else{ Sanjiaoxing s = new Sanjiaoxing(); s.a.x = Double.valueOf(point[1]); s.a.y = Double.valueOf(point[2]); s.b.x = Double.valueOf(point[3]); s.b.y = Double.valueOf(point[4]); s.c.x = Double.valueOf(point[5]); s.c.y = Double.valueOf(point[6]); double l1,l2,l3; l1 = Math.sqrt(Math.pow(s.a.x-s.b.x,2) + Math.pow(s.a.y-s.b.y,2)); l2 = Math.sqrt(Math.pow(s.a.x-s.c.x,2) + Math.pow(s.a.y-s.c.y,2)); l3 = Math.sqrt(Math.pow(s.b.x-s.c.x,2) + Math.pow(s.b.y-s.c.y,2)); if(l1+l2<=l3||l2+l3<=l1||l1+l3<=l2){ System.out.print("data error"); } else if(l1==l2&&l1==l3&&l2==l3){ System.out.print("true true"); } else if(l1==l2||l1==l3||l2==l3){ System.out.print("true false"); } else{ System.out.print("false false"); } }
第二问:
计算周长、面积、重心坐标:将三个点形成的三个线段长度相加即为周长,面积使用底乘高进行计算,即调用线中垂直距离进行计算,重心坐标可直接使用公式进行计算。
if(point.length!=7){ System.out.print("wrong number of points"); return; } else{ Sanjiaoxing s = new Sanjiaoxing(); s.a.x = Double.valueOf(point[1]); s.a.y = Double.valueOf(point[2]); s.b.x = Double.valueOf(point[3]); s.b.y = Double.valueOf(point[4]); s.c.x = Double.valueOf(point[5]); s.c.y = Double.valueOf(point[6]); double l1,l2,l3; l1 = Math.sqrt(Math.pow(s.a.x-s.b.x,2) + Math.pow(s.a.y-s.b.y,2)); l2 = Math.sqrt(Math.pow(s.a.x-s.c.x,2) + Math.pow(s.a.y-s.c.y,2)); l3 = Math.sqrt(Math.pow(s.b.x-s.c.x,2) + Math.pow(s.b.y-s.c.y,2)); if(l1+l2<=l3||l2+l3<=l1||l1+l3<=l2){ System.out.print("data error"); return; } else{ double C,S; Dian X = new Dian(); C = s.zhouchang(s); S = s.mianji(s); X = s.zhongxin(s); X.x = Math.round(X.x*1000000)/(double)1000000; X.y = Math.round(X.y*1000000)/(double)1000000; System.out.print(Math.round(C*1000000)/(double)1000000 + " " + Math.round(S*1000000)/(double)1000000 + " " + X.x + "," + X.y); } }
第三问:
判断三角形的类型:将三个点形成的三个线段长度进行比较即可。(需先判断钝角再判断直角,因为直角的判断条件钝角也适用,因此需先对钝角进行判断)
if(point.length!=7){ System.out.print("wrong number of points"); return; } else{ Sanjiaoxing s = new Sanjiaoxing(); s.a.x = Double.valueOf(point[1]); s.a.y = Double.valueOf(point[2]); s.b.x = Double.valueOf(point[3]); s.b.y = Double.valueOf(point[4]); s.c.x = Double.valueOf(point[5]); s.c.y = Double.valueOf(point[6]); double l1,l2,l3; l1 = Math.sqrt(Math.pow(s.a.x-s.b.x,2) + Math.pow(s.a.y-s.b.y,2)); l2 = Math.sqrt(Math.pow(s.a.x-s.c.x,2) + Math.pow(s.a.y-s.c.y,2)); l3 = Math.sqrt(Math.pow(s.b.x-s.c.x,2) + Math.pow(s.b.y-s.c.y,2)); double A,B,C; A=Math.pow(s.a.x-s.b.x,2) + Math.pow(s.a.y-s.b.y,2); B=Math.pow(s.a.x-s.c.x,2) + Math.pow(s.a.y-s.c.y,2); C=Math.pow(s.b.x-s.c.x,2) + Math.pow(s.b.y-s.c.y,2); if(l1+l2<=l3||l2+l3<=l1||l1+l3<=l2){ System.out.print("data error"); } else if((A+B<C)||(A+C<B)||(B+C<A)){ System.out.print("true false false"); } else if((A+B-C<0.00000000001)||(A+C-B<0.00000000001)||(B+C-A<0.00000000001)){ System.out.print("false true false"); } else{ System.out.print("false false true"); } }
第四问:
前两个点形成的直线与后三个点形成的三角形相交的判断:将前两个点形成的直线分别与三角形的三条边求交点,若交点在三角形上即为一个交点,若交点有两个,则用大三角形的面积减去小三角形的面积计算直线分割的两部分面积。(可使用三个flag标志记录交点位于三角形的哪条边,由此更加方便计算分割的面积)
if(point.length!=11){ System.out.print("wrong number of points"); return; } else{ Xian l = new Xian(); Sanjiaoxing s = new Sanjiaoxing(); l.a.x = Double.valueOf(point[1]); l.a.y = Double.valueOf(point[2]); l.b.x = Double.valueOf(point[3]); l.b.y = Double.valueOf(point[4]); if(l.a.x!=l.b.x) l.xl = l.xielv(); s.a.x = Double.valueOf(point[5]); s.a.y = Double.valueOf(point[6]); s.b.x = Double.valueOf(point[7]); s.b.y = Double.valueOf(point[8]); s.c.x = Double.valueOf(point[9]); s.c.y = Double.valueOf(point[10]); if(l.a.x==l.b.x&&l.a.y==l.b.y){ System.out.print("points coincide"); return; } else{ double l1,l2,l3; l1 = Math.sqrt(Math.pow(s.a.x-s.b.x,2) + Math.pow(s.a.y-s.b.y,2)); l2 = Math.sqrt(Math.pow(s.a.x-s.c.x,2) + Math.pow(s.a.y-s.c.y,2)); l3 = Math.sqrt(Math.pow(s.b.x-s.c.x,2) + Math.pow(s.b.y-s.c.y,2)); if(l1+l2<=l3||l2+l3<=l1||l1+l3<=l2){ System.out.print("data error"); return; } else{ Dian D1 = new Dian(); Dian D2 = new Dian(); Dian D3 = new Dian(); int f1=0,f2=0,f3=0,sum=0; Xian L1 = new Xian(); L1.a = s.a; L1.b = s.b; if(L1.a.x != L1.b.x) L1.xl = L1.xielv(); Xian L2 = new Xian(); L2.a = s.a; L2.b = s.c; if(L2.a.x != L2.b.x) L2.xl = L2.xielv(); Xian L3 = new Xian(); L3.a = s.b; L3.b = s.c; if(L3.a.x != L3.b.x) L3.xl = L3.xielv(); /*System.out.print(l.pingxing(L1)); System.out.print(l.pingxing(L2)); System.out.print(l.pingxing(L3));*/ if((l.pingxing(L1)==1&&l.chuizhijuli(s.a)==0)||(l.pingxing(L2)==1&&l.chuizhijuli(s.a)==0)||(l.pingxing(L3)==1&&l.chuizhijuli(s.c)==0)){ System.out.print("The point is on the edge of the triangle"); return; } else{ if(l.pingxing(L1)==0){ D1 = l.jiaodian(L1); //System.out.println(L1.a.x + "," + L1.a.y + " " + L1.b.x + "," + L1.b.y); //System.out.println(D1.x + "," + D1.y); if((D1.x==s.a.x&&D1.y==s.a.y)||(L1.xianshang(D1)==1)){ f1=1; sum++; }//System.out.println(f1); } if(l.pingxing(L2)==0){ D2 = l.jiaodian(L2); //System.out.println(D2.x + "," + D2.y); if((D2.x==s.c.x&&D2.y==s.c.y)||(L2.xianshang(D2)==1)){ f2=1; sum++; }//System.out.println(f2); } if(l.pingxing(L3)==0){ D3 = l.jiaodian(L3); //System.out.println(D3.x + "," + D3.y); //System.out.println(s.b.x + "," + s.b.y); if((D3.x==s.b.x&&D3.y==s.b.y)||(L3.xianshang(D3)==1)){ f3=1; sum++; }//System.out.println(f3); } if(sum==0){ System.out.print("0"); return; } else if(sum==1){ System.out.print("1"); return; } else{ double c1,d1,s1,S,s2; S = s.mianji(s); if(f1==1&&f2==1){ c1 = Math.sqrt(Math.pow(s.a.x-D1.x,2) + Math.pow(s.a.y-D1.y,2)); d1 = L1.chuizhijuli(s.c); s1=c1*d1/2; s2 = S - s1; } else if(f1==1&&f3==1){ c1 = Math.sqrt(Math.pow(s.b.x-D3.x,2) + Math.pow(s.b.y-D3.y,2)); d1 = L3.chuizhijuli(s.a); s1=c1*d1/2; s2 = S - s1; } else{ c1 = Math.sqrt(Math.pow(s.c.x-D2.x,2) + Math.pow(s.c.y-D2.y,2)); d1 = L2.chuizhijuli(s.b); s1=c1*d1/2; s2 = S - s1; } if(s1>s2){ System.out.print("2 "+Math.round(s2*1000000)/(double)1000000+" "+Math.round(s1*1000000)/(double)1000000); } else{ System.out.print("2 "+Math.round(s1*1000000)/(double)1000000+" "+Math.round(s2*1000000)/(double)1000000); } } } } } }
第五问:
判断点是否在三角形内:将该点分别与三角形的三个点形成直线,若三条直线与三角形均有两个交点(包括顶点),则该点位于三角形内。
if(point.length!=9){ System.out.print("wrong number of points"); return; } else{ Dian n = new Dian(); Sanjiaoxing s = new Sanjiaoxing(); n.x = Double.valueOf(point[1]); n.y = Double.valueOf(point[2]); s.a.x = Double.valueOf(point[3]); s.a.y = Double.valueOf(point[4]); s.b.x = Double.valueOf(point[5]); s.b.y = Double.valueOf(point[6]); s.c.x = Double.valueOf(point[7]); s.c.y = Double.valueOf(point[8]); double l1,l2,l3; l1 = Math.sqrt(Math.pow(s.a.x-s.b.x,2) + Math.pow(s.a.y-s.b.y,2)); l2 = Math.sqrt(Math.pow(s.a.x-s.c.x,2) + Math.pow(s.a.y-s.c.y,2)); l3 = Math.sqrt(Math.pow(s.b.x-s.c.x,2) + Math.pow(s.b.y-s.c.y,2)); if(l1+l2<=l3||l2+l3<=l1||l1+l3<=l2){ System.out.print("data error"); return; } else{ /*double a1,a2,a3,A,B,C; a1 =Math.sqrt(Math.pow(s.a.x-n.x,2) + Math.pow(s.a.y-n.y,2)); a2 =Math.sqrt(Math.pow(s.b.x-n.x,2) + Math.pow(s.b.y-n.y,2)); a3 =Math.sqrt(Math.pow(s.c.x-n.x,2) + Math.pow(s.c.y-n.y,2)); /*System.out.println(a1); System.out.println(a2); System.out.println(a3);*/ /*A=Math.sqrt(Math.pow(s.a.x-s.b.x,2) + Math.pow(s.a.y-s.b.y,2)); B=Math.sqrt(Math.pow(s.a.x-s.c.x,2) + Math.pow(s.a.y-s.c.y,2)); C=Math.sqrt(Math.pow(s.b.x-s.c.x,2) + Math.pow(s.b.y-s.c.y,2)); /*System.out.println(A); System.out.println(B); System.out.println(C);*/ /*if((A-a1-a2>0.0000001)||(B-a1-a3>0.0000001)||(C-a3-a2>0.000001)){ System.out.print("on the triangle"); return; }*/ Xian L1 = new Xian(); L1.a = s.a; L1.b = s.b; if(L1.a.x != L1.b.x) L1.xl = L1.xielv(); Xian L2 = new Xian(); L2.a = s.a; L2.b = s.c; if(L2.a.x != L2.b.x) L2.xl = L2.xielv(); Xian L3 = new Xian(); L3.a = s.b; L3.b = s.c; if(L3.a.x != L3.b.x) L3.xl = L3.xielv(); Xian n1 = new Xian(); n1.a = n; n1.b = s.c; if(n1.a.x!=n1.b.x) n1.xl = n1.xielv(); Xian n2 = new Xian(); n2.a = n; n2.b = s.b; if(n2.a.x!=n2.b.x) n2.xl = n2.xielv(); Xian n3 = new Xian(); n3.a = n; n3.b = s.a; if(n3.a.x!=n3.b.x) n3.xl = n3.xielv(); Dian D1 = new Dian(); Dian D2 = new Dian(); Dian D3 = new Dian(); D1 = n1.jiaodian(L1); D2 = n2.jiaodian(L2); D3 = n3.jiaodian(L3); /*System.out.println(D1.x + "," + D1.y); System.out.println(D2.x + "," + D2.y); System.out.println(D3.x + "," + D3.y); System.out.println(L1.xianshang(D1)); System.out.println(L2.xianshang(D2)); System.out.println(L3.xianshang(D3));*/ if((D1.x==n.x&&D1.y==n.y)||(D2.x==n.x&&D2.y==n.y)||(D3.x==n.x&&D3.y==n.y)||(s.a.x==n.x&&s.a.y==n.y)||(s.b.x==n.x&&s.b.y==n.y)||(s.c.x==n.x&&s.c.y==n.y)){ System.out.print("on the triangle"); return; } if(L1.xianshang(D1)==0||L2.xianshang(D2)==0||L3.xianshang(D3)==0){ System.out.print("outof triangle"); } else{ System.out.print("in the triangle"); } } }
代码分析:
由于本题使用的线类方法不适用于三角形的计算,因此本段代码在编写过程中需重新进行计算,对方法的使用更少了。不仅如此,由于对题目的思考不够透彻,有些情况为考虑充足,导致有些得分点无法通过。本题中还涉及到计算的误差,导致无法顺利得到想要的结果,后续还需继续改进。
踩坑心得:对于几何问题需要进行多方面的考虑,拥有多种情况的需要分开讨论。不仅如此,输入的非法判断也需要考虑多种情况,将字符串拆分判非法也需要多次拆分。
改进建议:为了更加方便地使用类,需要将线类中的一些方法换成其他计算方法,并将线的表达式改为Ax+By+C=0进行计算。同时,还需另外加入一个赋值的类,因为本段代码出现多次大段重复的赋值代码,使代码看起来复杂无序,需要进行进一步的优化。
总结:通过这三次题目集,我学会了如何初步使用面向对象的思维方式,学会了类、方法之间的调用关系,但是对于方法的选择还需改进,需要思考地更广泛,选择适合更多情况的方法进行计算。比如在进行三角形相关的计算时,发现线的方法大多不适用于三角形相关,于是又需重新进行编写,导致出现许多废代码。还需要尽量少使用判断语句增加圈复杂度,应多使用一些函数或者是更加简洁的方法,使代码更加精简,容易看懂。
标签:Dian,题目,point,Double,valueOf,return,Math From: https://www.cnblogs.com/-yyqx1128-/p/16749237.html