PTA题目集4、5与期中考试的总结
PTA题目集四、五与期中考试的阶段性总结
1.前言
第四次作业:
第一题:字符串匹配,难度一般,主要考察正则表达式。第二题:凸四边形的计算上,这道题目是在第三次作业三角形计算的基础上进行扩展,其中有许多方法可以直接调用上次写的三角形类,可以看出主要考察java不同类间的继承机制以及代码的合理构建。第三题:设计一个银行业务类,难度一般,主要考察java构造方法的创建和使用。
第五次作业:
本次作业将一个程序进行了功能上的拆分,主要是实现凸五边形的计算。这道题可以说是在四边形计算的基础上再上一层楼,较为困难,全体同学通过情况也不乐观。盲目沿用原来的架构极其容易导致bug难以发现以及文本量过高的问题,因此最好在写题目前构建好合理的继承关系,最好使用多态实现代码,以避免修改程序困难的情况。
期中考试:
第一题考察最基本的构造方法,第二题考察继承与多态的使用,第三题考察泛型与对象数组的合理使用,难度层层递进,总体来说只要读懂题目给的类图,明确抽象类和抽象方法,注意题目给的输入条件,解决起来还是比较轻松愉快的。
2.程序设计分析
第四次作业
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"结束。
输出格式:
与输入行相对应的各个整数之和。
输入样例1:
2012年6月27日11时47分,中国“蛟龙”再次刷新“中国深度”——下潜7062米
6月15日,6671米
6月19日,6965米
6月22日,6963米
6月24日,7020米
6月27日,7062米
下潜至7000米,标志着我国具备了载人到达全球99%以上海洋深处进行作业的能力
end
输出样例1:
9165
6692
6990
6991
7050
7095
7099
输入样例2:
全世界投入使用的各类载人潜水器约90艘,下潜深度超过1000米的仅有12艘,更深的潜水器数量更少
6000米以上深度载人潜水器的国家包括中国、美国、日本、法国和俄罗斯
日本深潜器下潜6527米,蛟龙号在马里亚纳海沟海试成功到达7020米海底,创造了新的世界纪录
从2009年至2012年,蛟龙号接连取得1000米级、3000米级、5000米级和7000米级海试成功
下潜至7000米,说明蛟龙号载人潜水器集成技术的成熟
end
输出样例2:
1102
6000
13547
20021
7000
源码:
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String pipei="[0-9]+";
Pattern pa=Pattern.compile(pipei);
Scanner sc= new Scanner(System.in);
String s1 = sc.nextLine();
while (!s1.equals("end"))
{
Matcher ma=pa.matcher(s1);
int num=0;
while (ma.find())
{
String group = ma.group();
int i = Integer.parseInt(group);
num+=i;
}
System.out.println(num);
s1=sc.nextLine();
}
}
}
类图如下:

SourceMonitor的代码分析图如下:


分析:
1.本题考察的是从每行字符串中提取数字,求得每行数字的和。这里我使用Pattern类和Matcher类配合正则表达式获取满足条件的字符串,之后通过Integer.parseInt()方法将字符串转为整型,将结果相加后输出即可。
2.由于题目较为简单,我没有考虑使用其他的类来辅助我实现部分功能,因此方法全都在Main中,导致类图较为简单,也没有其他的依赖关系。
3.通过分析代码分析图可得本作业的代码复杂度,圈复杂度都处于理想区间内,代码冗余度较低。
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
输出样例:
在这里给出相应的输出。例如:
Wrong Format
输入样例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:0,0 -10,100 0,99 10,100
输出样例:
在这里给出相应的输出。例如:
false 221.097 990.0
源码:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String s = sc.nextLine();
Judge judge=new Judge();
boolean b = judge.JudgeFormat(s);
if(!b)
{
return;
}
Switchs sw=new Switchs();
sw.choose(s);
}
}
class GetPoint{
public List<Point> getLocations(String s)
{
List<Point> list=new ArrayList<>();
String splits =null;
splits=s.split(":")[1];
String[] s2 = splits.split(" ");
for (String split : s2) {
String[] split1 = split.split(",");
double x = Double.parseDouble(split1[0]);
double y = Double.parseDouble(split1[1]);
Point point=new Point();
point.setX(x);
point.setY(y);
list.add(point);
}
return list;
}
}
class Line{
//获取两点距离
public double getLength(Point po1,Point po2)
{
double x1=po1.getX();
double y1=po1.getY();
double x2=po2.getX();
double y2=po2.getY();
return Math.sqrt(Math.pow((x1-x2),2)+Math.pow((y1-y2),2));
}
public double getSlope1(Point point1,Point point2)
{
//注意存在斜率不存在的情况
return (point2.getY()-point1.getY())/(point2.getX()-point1.getX());
}
public double getSlope(Point point1,Point point2,Point point3,Point point4)
{
double x1,x2,x3,x4,y1,y2,y3,y4;
x1=point1.getX();
y1=point1.getY();
x2=point2.getX();
y2=point2.getY();
x3=point3.getX();
y3=point3.getY();
x4=point4.getX();
y4=point4.getY();
double A1,B1,A2,B2;
A1 = y2-y1;
B1 = x1-x2;
A2 = y4-y3;
B2 = x3-x4;
double v = A1 * B2 - A2 * B1;
// System.out.println(v);
return v;
}
//获取两直线交点
public List<Double> intersection(Point point1,Point point2,Point point3,Point point4)
{
double x1,x2,x3,x4,y1,y2,y3,y4;
List<Double> list=new ArrayList<>();
x1=point1.getX();
y1=point1.getY();
x2=point2.getX();
y2=point2.getY();
x3=point3.getX();
y3=point3.getY();
x4=point4.getX();
y4=point4.getY();
double A1,B1,C1,A2,B2,C2;
A1 = y2-y1;
B1 = x1-x2;
C1 = x2*y1 -x1*y2;
A2 = y4-y3;
B2 = x3-x4;
C2 = x4*y3-x3*y4;
if(A1*B2-A2*B1==0)
{
double x=999898;
double y=478478;
list.add(x);
list.add(y);
return list;
}
double x =((B2*C1-B1*C2) / (A2*B1-A1*B2));
double y =((A1*C2-A2*C1) / (A2*B1-A1*B2));
list.add(x);
list.add(y);
return list;
}
//判断交点是否在线段内
public boolean inline(Point point1,Point point2,Point point3,Point point4)
{
List<Double> intersection = intersection(point1,point2,point3,point4);
double x1,x2,x3,x4,y1,y2,y3,y4;
x1=point1.getX();
y1=point1.getY();
x2=point2.getX();
y2=point2.getY();
x3=point3.getX();
y3=point3.getY();
x4=point4.getX();
y4=point4.getY();
Double x = intersection.get(0);
Double y = intersection.get(1);
if(((x-x1)*(x-x2)<0||(y-y1)*(y-y2)<0)&&((x-x3)*(x-x4)<0||(y-y3)*(y-y4)<0))
{
return true;
}
else {
return false;
}
}
}
class Point{
private double x;
private double y;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}
class Judge{
Line line=new Line();
//判断是否构成四边形
public boolean Judge_quadrangle(List<Point> locations)
{
Line line=new Line();
Point point1 = locations.get(0);
Point point2 = locations.get(1);
Point point3 = locations.get(2);
Point point4 = locations.get(3);
boolean res1= line.inline(point1, point2, point3, point4);
boolean res2 = line.inline(point2, point3, point4, point1);
int res3 = Collinear(point1, point2, point3);
int res4 = Collinear(point2, point3, point4);
int res5 = Collinear(point3, point4, point1);
int res6 = Collinear(point4, point1, point2);
if(res3==1||res4==1||res5==1||res6==1)
{
return false;
}
else {
if(res1||res2)
{
return false;
}
else {
return true;
}
}
}
//判断三点是否共线
public int Collinear(Point point1,Point point2,Point point3){
double x1, x2, x3,y1,y2,y3;
x1=point1.getX();
x2=point2.getX();
x3=point3.getX();
y1=point1.getY();
y2=point2.getY();
y3=point3.getY();
double k1,b1,c1;
k1 = y2-y1;
b1 = x1-x2;
c1 = x2*y1-x1*y2;
if(k1*x3+b1*y3+c1==0){
return 1;
}
else{
if(k1*x3+b1*y3+c1<0){
return -1;
}
else{
return 0;
}
}
}
public boolean Judge_num(int num,String s)
{
String s1 = s.split(":")[1];
String[] s2 = s1.split(" ");
switch (num)
{
case 1:
case 2:
case 3: {
if(s2.length!=4)
{
return false;
}
break;
}
case 4:{
if(s2.length!=6)
{
return false;
}
break;
}
case 5:{
if(s2.length!=5)
{
return false;
}
break;
}
}
return true;
}
public boolean JudgeFormat(String s)
{
if(s.length()<=2)
{
System.out.println("Wrong Format");
return false;
}
char cc = s.charAt(0);
int i=cc-'0';
if(!(i<=5&&i>=1))
{
System.out.println("Wrong Format");
return false;
}
if(s.charAt(1)!=':')
{
System.out.println("Wrong Format");
return false;
}
String s1 = s.split(":")[1];
String[] s2 = s1.split(" ");
for (String s3 : s2) {
String[] split = s3.split(",");
if (split.length!=2)
{
System.out.println("Wrong Format");
return false;
}
for (String s4 : split) {
if(!s4.matches("^[+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?)"))
{
System.out.println("Wrong Format");
return false;
}
}
}
return true;
}
//判断两边是否平行且相等
public boolean Judge_parall(Point point1,Point point2,Point point3,Point point4)
{
Line line=new Line();
double slope1 = line.getSlope(point1, point2,point3,point4);
double slope2 = line.getSlope(point2, point3,point1,point4);
if(slope1==0&&slope2==0)
{
return true;
}
else {
return false;
}
}
//判断四条边是否相等,判断菱形
public boolean judge_diamond(Point point1,Point point2,Point point3,Point point4)
{
double length1 = line.getLength(point1, point2);
double length2 = line.getLength(point2, point3);
double length3 = line.getLength(point3, point4);
double length4 = line.getLength(point4, point1);
if(length1==length2&&length1==length3&&length1==length4&&length2==length3&&length2==length4&&length3==length4)
{
return true;
}
else {
return false;
}
}
//判断矩形
public boolean judge_rectangle(Point point1,Point point2,Point point3,Point point4)
{
double length1 = line.getLength(point1, point3);
double length2 = line.getLength(point2, point4);
if(Math.abs(length2-length1)<0.1)
{
return true;
}
else {
return false;
}
}
//数组去重方法,返回去重后的数组
public List<Point> Delete_Duplicates(List<Point> list)
{
List<Point> res =new ArrayList<>();
for (int i=0;i<list.size();i++)
{
int flag=0;
for(int j=i+1;j<list.size();j++)
{
double x=list.get(j).getX();
double y=list.get(j).getY();
if(x==list.get(i).getX()&&y==list.get(i).getY())
{
flag=1;
break;
}
}
if(flag==0)
{
res.add(list.get(i));
}
}
return res;
}
//判断是否在线段内
public boolean confirm(Point inter,Point point2,Point point3)
{
double x= inter.getX();
double y= inter.getY();
double x1,x2,y1,y2;
x1=point2.getX();
x2=point3.getX();
y1=point2.getY();
y2=point3.getY();
if(((x-x1)*(x-x2))<0||((y-y1)*(y-y2))<0)
{
return true;
}
else
{
return false;
}
}
public void inside_triangle(List<Point> resultList,Point key)
{
Area area=new Area();
Point trianglePoint1 = resultList.get(0);
Point trianglePoint2 = resultList.get(1);
Point trianglePoint3 = resultList.get(2);
int collinear = Collinear(trianglePoint1, trianglePoint2, trianglePoint3);
//说明共线,不符合三角形,退出。
if (collinear == 1) {
System.out.println("not a quadrilateral or triangle");
}
// 是三角形
else {
//获得总面积
double totalArea = area.getArea(trianglePoint1, trianglePoint2, trianglePoint3);
double area1 = area.getArea(trianglePoint1, trianglePoint2, key);
double area2 = area.getArea(trianglePoint2, trianglePoint3, key);
double area3 = area.getArea(trianglePoint1, trianglePoint3, key);
if(Math.abs((area1+area2+area3)-totalArea)>0.01)
{
System.out.println("outof the triangle");
return;
}
else {
int collinear1 = Collinear(trianglePoint1, trianglePoint2, key);
int collinear2 = Collinear(trianglePoint2, trianglePoint3, key);
int collinear3 = Collinear(trianglePoint3, trianglePoint1, key);
if(collinear1==1||collinear2==1||collinear3==1)
{
System.out.println("on the triangle");
return;
}
else
{
System.out.println("in the triangle");
}
}
}
}
public void inside_quadrilateral(List<Point> resultList,Point key)
{
Area area=new Area();
Point point1=resultList.get(0);
Point point2=resultList.get(1);
Point point3=resultList.get(2);
Point point4=resultList.get(3);
double area1 = area.getArea(point1, point2, point3);
double area2 = area.getArea(point3, point4, point1);
double totalArea=area1+area2;
double area3 = area.getArea(point1, point2, key);
double area4 = area.getArea(point2, point3, key);
double area5 = area.getArea(point3, point4, key);
double area6 = area.getArea(point4, point1, key);
if(Math.abs((area3+area4+area5+area6)-totalArea)>0.01)
{
System.out.println("outof the quadrilateral");
}else {
int collinear1 = Collinear(point1, point2, key);
int collinear2 = Collinear(point2, point3, key);
int collinear3 = Collinear(point3, point4, key);
int collinear4 = Collinear(point4, point1, key);
if(collinear1==1||collinear2==1||collinear3==1||collinear4==1)
{
System.out.println("on the quadrilateral");
}
else {
System.out.println("in the quadrilateral");
}
}
}
}
class Switchs{
public void choose(String s)
{
int i = s.charAt(0) - '0';
switch (i)
{
case 1:{
situation1 s1=new situation1();
s1.handle(s);
break;
}
case 2:{
situation2 s2=new situation2();
s2.handle(s);
break;
}
case 3:{
situation3 s3=new situation3();
s3.handle(s);
break;
}
case 4:{
situation4 s4=new situation4();
s4.handle(s);
break;
}
case 5:{
situation5 s5=new situation5();
s5.handle(s);
break;
}
}
}
}
class situation1{
GetPoint po=new GetPoint();
Judge judge=new Judge();
Line line=new Line();
public void handle(String s)
{
if(!judge.Judge_num(1,s))
{
System.out.println("wrong number of points");
return;
}
List<Point> locations = po.getLocations(s);
Point point1 = locations.get(0);
Point point2 = locations.get(1);
Point point3 = locations.get(2);
Point point4 = locations.get(3);
double x1,x2,x3,x4,y1,y2,y3,y4;
x1=point1.getX();
y1=point1.getY();
x2=point2.getX();
y2=point2.getY();
x3=point3.getX();
y3=point3.getY();
x4=point4.getX();
y4=point4.getY();
if(x1==x2&&y1==y2||x1==x3&&y1==y3||x1==x4&&y1==y4||x2==x3&&y2==y3||x2==x4&&y2==y4||x3==x4&&y3==y4)
{
System.out.println("points coincide");
return;
}
boolean res = judge.Judge_quadrangle(locations);
boolean b1 = judge.Judge_parall(point1, point2, point3, point4);
if(!res)
{
System.out.println("false false");
}
else {
if(b1)
{
System.out.println("true true");
}
else {
System.out.println("true false");
}
}
}
}
class situation2{
GetPoint po=new GetPoint();
Judge judge=new Judge();
Line line=new Line();
public void handle(String s)
{
if(!judge.Judge_num(2,s))
{
System.out.println("wrong number of points");
return;
}
List<Point> locations = po.getLocations(s);
Point point1 = locations.get(0);
Point point2 = locations.get(1);
Point point3 = locations.get(2);
Point point4 = locations.get(3);
boolean res = judge.Judge_quadrangle(locations);
//如果不能组成四边形
if(!res)
{
System.out.println("not a quadrilateral");
}
else {
boolean b1 = judge.Judge_parall(point1, point2, point3, point4);
//能组成四边形但不是平行四边形
if(!b1)
{
System.out.println(false+" "+false+" "+false);
}
else {
// 1.先判断时候否是棱形
boolean res1 = judge.judge_diamond(point1, point2, point3, point4);
// 2.在判断是否是矩形
boolean res2 = judge.judge_rectangle(point1, point2, point3, point4);
if(res1&&res2)
{
System.out.println(true+" "+true+" "+true);
}
else if(res1){
System.out.println(true+" "+false+" "+false);
}
else if(res2)
{
System.out.println(false+" "+true+" "+false);
}
//如果只是一般平行四边形
else {
System.out.println(false+" "+false+" "+false);
}
}
}
}
}
class situation3{
OutputFormats out=new OutputFormats();
GetPoint po=new GetPoint();
Judge judge=new Judge();
Line line=new Line();
Area area=new Area();
public void handle(String s)
{
if(!judge.Judge_num(3,s))
{
System.out.println("wrong number of points");
return;
}
List<Point> locations = po.getLocations(s);
Point point1 = locations.get(0);
Point point2 = locations.get(1);
Point point3 = locations.get(2);
Point point4 = locations.get(3);
//获得坐标
boolean res = judge.Judge_quadrangle(locations);
double totallen,totalArea;
double len1,len2,len3,len4;
double rounding2;
len1=line.getLength(point2,point1);
len2=line.getLength(point3,point2);
len3=line.getLength(point4,point3);
len4=line.getLength(point1,point4);
totallen=len1+len2+len3+len4;
double rounding1 = out.rounding(totallen);
//如果不能组成四边形
if(!res)
{
System.out.println("not a quadrilateral");
}
else
{
boolean result;
double area1 = area.getArea(point1, point2, point3);
double area2 = area.getArea(point3, point4, point1);
double area3 = area.getArea(point1, point2, point4);
double area4 = area.getArea(point2, point3, point4);
if(Math.abs((area1+area2)-(area3+area4))<0.01)
{
result=true;
}
else {
result=false;
}
//返回true,说明是凸四边形
if(result)
{
//面积
totalArea=area1+area2;
rounding2 = out.rounding(totalArea);
System.out.println(true+" "+rounding1+" "+rounding2);
}
//返回false,说明是凹四边形
else {
if(((area1+area2)-(area3+area4))>0)
{
totalArea=area3+area4;
}
else {
totalArea=area1+area2;
}
rounding2 = out.rounding(totalArea);
System.out.println(false+" "+rounding1+" "+rounding2);
}
}
}
}
class situation4{
GetPoint po=new GetPoint();
Judge judge=new Judge();
Line line=new Line();
Area area=new Area();
public void handle(String s)
{
List<Point> temps=new ArrayList<>();
if(!judge.Judge_num(4,s))
{
System.out.println("wrong number of points");
return;
}
List<Point> locations = po.getLocations(s);
//判断重复的暂存数组
List<Point> temp =new ArrayList<>();
Point point1 = locations.get(0);
Point point2 = locations.get(1);
Point point3 = locations.get(2);
Point point4 = locations.get(3);
Point point5 = locations.get(4);
Point point6 = locations.get(5);
if(point1.getX()==point2.getX()&&point1.getY()==point2.getY())
{
System.out.println("points coincide");
return;
}
temp.add(point3);
temp.add(point4);
temp.add(point5);
temp.add(point6);
// 去重,返回处理后数组长度
List<Point> resultList = judge.Delete_Duplicates(temp);
//去重后剩三个点,说明有可能是三角形,需要进一步判断
if(resultList.size()==3) {
//先判断能不能组成三角形,即三点不共线
// 先获取点
Point trianglePoint1 = resultList.get(0);
Point trianglePoint2 = resultList.get(1);
Point trianglePoint3 = resultList.get(2);
int collinear = judge.Collinear(trianglePoint1, trianglePoint2, trianglePoint3);
//说明共线,不符合三角形,退出。
if (collinear == 1) {
System.out.println("not a quadrilateral or triangle");
}
//说明是三角形
else {
//判断直线与三角形位置,如果三角形两端点与直线共线,则输出错误信息
int collinear1 = judge.Collinear(point1, point2, trianglePoint1);
int collinear2 = judge.Collinear(point1, point2, trianglePoint2);
int collinear3 = judge.Collinear(point1, point2, trianglePoint3);
if (collinear1 == 1 && collinear2 == 1 || collinear1 == 1 && collinear3 == 1 || collinear2 == 1 && collinear3 == 1) {
System.out.println("The line is coincide with one of the lines");
}
//否则说明直线与三角形边不重合,开始判断直线与三角形截线关系,可调参
else {
// System.out.println("存在截线");
temps.add(point1);
temps.add(point2);
temps.add(resultList.get(0));
temps.add(resultList.get(1));
temps.add(resultList.get(2));
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
}
}
else if(resultList.size()==4){
//四点情况,需要判断能否组成四边形
List<Point> tempss=new ArrayList<>();
tempss.add(point3);
tempss.add(point4);
tempss.add(point5);
tempss.add(point6);
boolean b = judge.Judge_quadrangle(tempss);
//如果能组成四边形
if(b)
{
int collinear1 = judge.Collinear(point1, point2, point3);
int collinear2 = judge.Collinear(point1, point2, point4);
int collinear3 = judge.Collinear(point1, point2, point5);
int collinear4 = judge.Collinear(point1, point2, point6);
if (collinear1 == 1 && collinear2 == 1 || collinear2 == 1 && collinear3 == 1 || collinear3 == 1 && collinear4 == 1|| collinear4 == 1 && collinear1 == 1) {
System.out.println("The line is coincide with one of the lines");
return;
}
//具体判断截线与边的情况
area.Quadrilateral_sectional_area(locations);
}
//如果四点不能组成四边形,判断是否组成三角形
else {
int collinear1 = judge.Collinear(point3, point5, point4);
int collinear2 = judge.Collinear(point4, point6, point5);
int collinear3 = judge.Collinear(point5, point3, point6);
int collinear4 = judge.Collinear(point6, point4, point3);
boolean confirm1 = judge.confirm(point4, point3, point5);
boolean confirm2 = judge.confirm(point5, point4, point6);
boolean confirm3 = judge.confirm(point6, point5, point3);
boolean confirm4 = judge.confirm(point3, point6, point4);
if(collinear1==1||collinear2==1||collinear3==1||collinear4==1)
{
if(collinear1==1&&confirm1)
{
temps.add(point1);
temps.add(point2);
temps.add(point3);
temps.add(point5);
temps.add(point6);
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
else if(collinear2==1&&confirm2)
{
temps.add(point1);
temps.add(point2);
temps.add(point3);
temps.add(point4);
temps.add(point6);
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
else if(collinear3==1&&confirm3)
{
temps.add(point1);
temps.add(point2);
temps.add(point3);
temps.add(point4);
temps.add(point5);
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
else if(collinear4==1&&confirm4)
{
temps.add(point1);
temps.add(point2);
temps.add(point4);
temps.add(point5);
temps.add(point6);
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
else {
System.out.println("not a quadrilateral or triangle");
}
}
else {
System.out.println("not a quadrilateral or triangle");
}
}
}else {
System.out.println("not a quadrilateral or triangle");
}
}
}
class situation5{
GetPoint po=new GetPoint();
Judge judge=new Judge();
Line line=new Line();
Area area=new Area();
public void handle(String s)
{
if(!judge.Judge_num(5,s))
{
System.out.println("wrong number of points");
return;
}
List<Point> locations = po.getLocations(s);
//判断重复的暂存数组
List<Point> temp =new ArrayList<>();
Point point1 = locations.get(0);
Point point2 = locations.get(1);
Point point3 = locations.get(2);
Point point4 = locations.get(3);
Point point5 = locations.get(4);
temp.add(point2);
temp.add(point3);
temp.add(point4);
temp.add(point5);
// 去重,返回处理后数组长度
List<Point> resultList = judge.Delete_Duplicates(temp);
if(resultList.size()==3)
{
judge.inside_triangle(resultList,point1);
}
else if(resultList.size()==4)
{
boolean b = judge.Judge_quadrangle(resultList);
if(b)
{
judge.inside_quadrilateral(resultList,point1);
}
else {
// System.out.println("四点中的三点情况,判断能否组成三角形");
int collinear1 = judge.Collinear(point2, point4, point3);
int collinear2 = judge.Collinear(point3, point5, point4);
int collinear3 = judge.Collinear(point4, point2, point5);
int collinear4 = judge.Collinear(point5, point3, point2);
boolean confirm1 = judge.confirm(point3, point2, point4);
boolean confirm2 = judge.confirm(point4, point3, point5);
boolean confirm3 = judge.confirm(point5, point2, point4);
boolean confirm4 = judge.confirm(point2, point3, point5);
List<Point> temps=new ArrayList<>();
if(collinear1==1||collinear2==1||collinear3==1||collinear4==1)
{
if(collinear1==1&&confirm1)
{
temps.add(point2);
temps.add(point4);
temps.add(point5);
judge.inside_triangle(temps,point1);
}
else if(collinear2==1&&confirm2)
{
temps.add(point2);
temps.add(point3);
temps.add(point5);
judge.inside_triangle(temps,point1);
}
else if(collinear3==1&&confirm3)
{
temps.add(point2);
temps.add(point3);
temps.add(point4);
judge.inside_triangle(temps,point1);
}
else if(collinear4==1&&confirm4)
{
temps.add(point3);
temps.add(point4);
temps.add(point5);
judge.inside_triangle(temps,point1);
}
else {
System.out.println("not a quadrilateral or triangle");
}
}
else {
System.out.println("not a quadrilateral or triangle");
}
}
}else {
System.out.println("not a quadrilateral or triangle");
}
}
}
//面积类
class Area{
Line line=new Line();
Judge judge=new Judge();
//获得指定三点组成三角形的面积
public double getArea(Point point1,Point point2,Point point3)
{
double length1 = line.getLength(point1, point2);
double length2 = line.getLength(point2, point3);
double length3 = line.getLength(point1, point3);
double len=length1+length2+length3;
double p=len/2;
//获得面积
double era =Math.pow((p*(p-length1)*(p-length2)*(p-length3)),0.5);
return era;
}
public void getTriangular_sectional_area(List<Point> list)
{
Point point1 = list.get(0);
Point point2 = list.get(1);
Point point3 = list.get(2);
Point point4 = list.get(3);
Point point5 = list.get(4);
int collinear = judge.Collinear(point3,point4,point5);
//说明共线,不符合三角形,退出。
if (collinear == 1) {
System.out.println("not a quadrilateral or triangle");
return;
}
//判断直线是否与三角形三个点中的两个点共线
int collinear5 = judge.Collinear(point1, point2, point3);
int collinear6 = judge.Collinear(point1, point2, point4);
int collinear7 = judge.Collinear(point1, point2, point5);
if (collinear5 == 1 && collinear6 == 1 || collinear6 == 1 && collinear7 == 1 ||collinear5==1&&collinear7==1 ) {
System.out.println("The line is coincide with one of the lines");
return;
}
List<Double> in1 = line.intersection(point1,point2,point3,point4);
List<Double> in2 = line.intersection(point1,point2,point3,point5);
List<Double> in3 = line.intersection(point1,point2,point4,point5);
List<List<Double>> in4=new ArrayList<>();
//判断交点是否在三角形边上
Point inter1=new Point();
Point inter2=new Point();
Point inter3=new Point();
inter1.setX(in1.get(0));
inter1.setY(in1.get(1));
inter2.setX(in2.get(0));
inter2.setY(in2.get(1));
inter3.setX(in3.get(0));
inter3.setY(in3.get(1));
boolean com1 = judge.confirm(inter1,point3,point4);
boolean com2 = judge.confirm(inter2,point3,point5);
boolean com3 = judge.confirm(inter3,point4,point5);
//将得到的坐标去重,加入list表中
//如果是三角形三点中的一个,直接加入表中
if((in1.get(0)==(point3.getX())&&in1.get(1)==(point3.getY()))||(in1.get(0)==point4.getX()&&in1.get(1)==point4.getY())||(in1.get(0)==point5.getX()&&in1.get(1)==point5.getY()))
{
if(in4.size()!=0)
{
int flag=0;
for (List<Double> doubles : in4) {
Double aDouble = doubles.get(0);
Double aDouble1 = doubles.get(1);
boolean b = (in1.get(0)-aDouble==0) && (in1.get(1)-aDouble1==0);
if(b)
{
flag=1;
break;
}
}
if(flag==0)
{
in4.add(in1);
}
}
else if (in4.size()==0) {
in4.add(in1);
}
}
if((in2.get(0)==(point3.getX())&&in2.get(1)==(point3.getY()))||(in2.get(0)==point4.getX()&&in2.get(1)==point4.getY())||(in2.get(0)==point5.getX()&&in2.get(1)==point5.getY()))
{
if(in4.size()!=0)
{
int flag=0;
for (List<Double> doubles : in4) {
Double aDouble = doubles.get(0);
Double aDouble1 = doubles.get(1);
boolean b = (in2.get(0)-aDouble==0) && (in2.get(1)-aDouble1==0);
if(b)
{
flag=1;
break;
}
}
if(flag==0)
{
in4.add(in2);
}
}
else if (in4.size()==0) {
in4.add(in2);
}
}
if((in3.get(0)==(point3.getX())&&in3.get(1)==(point3.getY()))||(in3.get(0)==point4.getX()&&in3.get(1)==point4.getY())||(in3.get(0)==point5.getX()&&in3.get(1)==point5.getY()))
{
if(in4.size()!=0)
{
int flag=0;
for (List<Double> doubles : in4) {
Double aDouble = doubles.get(0);
Double aDouble1 = doubles.get(1);
boolean b = (in3.get(0)-aDouble==0) && (in3.get(1)-aDouble1==0);
if(b)
{
flag=1;
break;
}
}
if(flag==0)
{
in4.add(in3);
}
}
else if (in4.size()==0){
in4.add(in3);
}
}
//如果交点是三角形三点之一,直接将交点坐标加入结果数组
if(com1)
{
in4.add(in1);
}
if(com2)
{
in4.add(in2);
}
if(com3)
{
in4.add(in3);
}
if(in4.size()<2)
{
if(in4.size()==0)
{
System.out.println(0);
return;
}
else if(in4.size()==1)
{
System.out.println(1);
return;
}
}
//两交点的情况0
if(in4.size()==2){
// System.out.println(in4);
Point jiedian1=new Point();
Point jiedian2=new Point();
jiedian1.setX(in4.get(0).get(0));
jiedian1.setY(in4.get(0).get(1));
jiedian2.setX(in4.get(1).get(0));
jiedian2.setY(in4.get(1).get(1));
//判断三角形三点相对于线段的位置
int judge1 = judge.Collinear(jiedian1,jiedian2,point3);
int judge2 = judge.Collinear(jiedian1,jiedian2,point4);
int judge3 =judge.Collinear(jiedian1,jiedian2,point5);
double area=getArea(point3,point4,point5);
// System.out.println("大三角形面积"+area);
List<Double> temp=new ArrayList<>();
List<String> result=new ArrayList<>();
//三角形三个点都没有存在于截线上
if(judge3!=1&&judge1!=1&&judge2!=1)
{
double era1=0;
//说明第三点与截线组成三角形
if(judge1==judge2)
{
era1 = getArea(jiedian1,jiedian2,point5);
}
//说明第二点与截线组成三角形
else if(judge1==judge3)
{
era1 =getArea(jiedian1,jiedian2,point4);
}
//说明第一点与截线组成三角形
else if(judge2==judge3)
{
era1 = getArea(jiedian1,jiedian2,point3);
}
double era2 = area - era1;
OutputFormats formats=new OutputFormats();
era1 = formats.rounding(era1);
era2 = formats.rounding(era2);
if(era2>era1)
{
System.out.println(2+" "+era1+" "+era2);
}
else{
System.out.println(2+" "+era2+" "+era1);
}
}
//截线与三角形中一点相交
else if(judge3==1||judge1==1||judge2==1)
{
double era1=0;
if(judge1==1)
{
era1= getArea(jiedian1,jiedian2,point4);
}
else if(judge2==1)
{
era1= getArea(jiedian1,jiedian2,point3);
}
else if(judge3==1)
{
era1= getArea(jiedian1,jiedian2,point3);
}
double era2 = area - era1;
//四舍五入,保留三位有效数字
OutputFormats formats=new OutputFormats();
era1 = formats.rounding(era1);
era2 = formats.rounding(era2);
if(era2>era1)
{
System.out.println(2+" "+era1+" "+era2);
}
else{
System.out.println(2+" "+era2+" "+era1);
}
}
}
}
//获得四边形截线面积
public void Quadrilateral_sectional_area(List<Point> list)
{
OutputFormats formats=new OutputFormats();
// 1.直线与四边形四边交点,比较是否在线段内,
//获得6个具体点
Point point1 = list.get(0);
Point point2 = list.get(1);
Point point3 = list.get(2);
Point point4 = list.get(3);
Point point5 = list.get(4);
Point point6 = list.get(5);
List<Double> in1 = line.intersection(point1,point2,point3,point4);
List<Double> in2 = line.intersection(point1,point2,point4,point5);
List<Double> in3 = line.intersection(point1,point2,point5,point6);
List<Double> in4 = line.intersection(point1,point2,point6,point3);
List<List<Double>> in5=new ArrayList<>();
//判断交点是否在四边形边上
Point inter1=new Point();
Point inter2=new Point();
Point inter3=new Point();
Point inter4=new Point();
inter1.setX(in1.get(0));
inter1.setY(in1.get(1));
inter2.setX(in2.get(0));
inter2.setY(in2.get(1));
inter3.setX(in3.get(0));
inter3.setY(in3.get(1));
inter4.setX(in4.get(0));
inter4.setY(in4.get(1));
boolean com1 = judge.confirm(inter1,point3,point4);
boolean com2 = judge.confirm(inter2,point4,point5);
boolean com3 = judge.confirm(inter3,point5,point6);
boolean com4 = judge.confirm(inter4,point6,point3);
// System.out.println(com1);
// System.out.println(com2);
// System.out.println(com3);
//将得到的坐标去重,加入list表中
//如果是四边形四点中的一个,直接加入表中
if((in1.get(0)==(point3.getX())&&in1.get(1)==(point3.getY()))||(in1.get(0)==point4.getX()&&in1.get(1)==point4.getY())||(in1.get(0)==point5.getX()&&in1.get(1)==point5.getY())||(in1.get(0)==point6.getX()&&in1.get(1)==point6.getY()))
{
if(in5.size()!=0)
{
int flag=0;
for (List<Double> doubles : in5) {
Double aDouble = doubles.get(0);
Double aDouble1 = doubles.get(1);
boolean b = (in1.get(0)-aDouble==0) && (in1.get(1)-aDouble1==0);
if(b)
{
flag=1;
break;
}
}
if(flag==0)
{
in5.add(in1);
}
}
else if (in5.size()==0) {
in5.add(in1);
}
}
if((in2.get(0)==(point3.getX())&&in2.get(1)==(point3.getY()))||(in2.get(0)==point4.getX()&&in2.get(1)==point4.getY())||(in2.get(0)==point5.getX()&&in2.get(1)==point5.getY())||(in2.get(0)==point6.getX()&&in2.get(1)==point6.getY()))
{
if(in5.size()!=0)
{
int flag=0;
for (List<Double> doubles : in5) {
Double aDouble = doubles.get(0);
Double aDouble1 = doubles.get(1);
boolean b = (in2.get(0)-aDouble==0) && (in2.get(1)-aDouble1==0);
if(b)
{
flag=1;
break;
}
}
if(flag==0)
{
in5.add(in2);
}
}
else if (in5.size()==0) {
in5.add(in2);
}
}
if((in3.get(0)==(point3.getX())&&in3.get(1)==(point3.getY()))||(in3.get(0)==point4.getX()&&in3.get(1)==point4.getY())||(in3.get(0)==point5.getX()&&in3.get(1)==point5.getY())||(in3.get(0)==point6.getX()&&in3.get(1)==point6.getY()))
{
if(in5.size()!=0)
{
int flag=0;
for (List<Double> doubles : in5) {
Double aDouble = doubles.get(0);
Double aDouble1 = doubles.get(1);
boolean b = (in3.get(0)-aDouble==0) && (in3.get(1)-aDouble1==0);
if(b)
{
flag=1;
break;
}
}
if(flag==0)
{
in5.add(in3);
}
}
else if (in5.size()==0){
in5.add(in3);
}
}
if((in4.get(0)==(point3.getX())&&in4.get(1)==(point3.getY()))||(in4.get(0)==point4.getX()&&in4.get(1)==point4.getY())||(in4.get(0)==point5.getX()&&in4.get(1)==point5.getY())||(in4.get(0)==point6.getX()&&in4.get(1)==point6.getY()))
{
if(in5.size()!=0)
{
int flag=0;
for (List<Double> doubles : in5) {
Double aDouble = doubles.get(0);
Double aDouble1 = doubles.get(1);
boolean b = (in4.get(0)-aDouble==0) && (in4.get(1)-aDouble1==0);
if(b)
{
flag=1;
break;
}
}
if(flag==0)
{
in5.add(in3);
}
}
else if (in5.size()==0){
in5.add(in3);
}
}
//如果交点是三角形三点之一,直接将交点坐标加入结果数组
if(com1)
{
in5.add(in1);
}
if(com2)
{
in5.add(in2);
}
if(com3)
{
in5.add(in3);
}
if(com4)
{
in5.add(in4);
}
if(in5.size()<2)
{
if(in5.size()==0)
{
System.out.println(0);
return;
}
else if(in5.size()==1)
{
System.out.println(1);
return;
}
}
//两交点的情况0
if(in5.size()==2){
Point jiedian1=new Point();
Point jiedian2=new Point();
jiedian1.setX(in5.get(0).get(0));
jiedian1.setY(in5.get(0).get(1));
jiedian2.setX(in5.get(1).get(0));
jiedian2.setY(in5.get(1).get(1));
//判断四边形四点相对于线段的位置
int judge1 = judge.Collinear(jiedian1,jiedian2,point3);
int judge2 = judge.Collinear(jiedian1,jiedian2,point4);
int judge3 =judge.Collinear(jiedian1,jiedian2,point5);
int judge4 = judge.Collinear(jiedian1,jiedian2,point6);
double toarea1=getArea(point3,point4,point5);
double toarea2=getArea(point5,point6,point3);
//总面积
double totalArea=toarea1+toarea2;
double area1,area2,part1 = 0,part2 = 0;
//四边形四个点都没有存在于截线上
if(judge3!=1&&judge1!=1&&judge2!=1&&judge4!=1)
{
if(judge1==judge2)
{
area1=getArea(point3,point4,jiedian1);
area2=getArea(point3,point4,jiedian2);
part1=area1+area2;
part2=totalArea-part1;
}
else if(judge1==judge4)
{
area1=getArea(point3,point6,jiedian1);
area2=getArea(point3,point6,jiedian2);
part1=area1+area2;
part2=totalArea-part1;
}
else if(judge1==judge2&&judge2==judge3)
{
part1=getArea(jiedian1,jiedian2,point6);
part2=totalArea-part1;
}
else if(judge2==judge3&&judge3==judge4)
{
part1=getArea(jiedian1,jiedian2,point3);
part2=totalArea-part1;
}
else if(judge1==judge3&&judge3==judge4)
{
part1=getArea(jiedian1,jiedian2,point4);
part2=totalArea-part1;
}
else if(judge1==judge4&&judge2==judge4)
{
part1=getArea(jiedian1,jiedian2,point5);
part2=totalArea-part1;
}
part1=formats.rounding(part1);
part2=formats.rounding(part2);
if(part1>part2)
{
System.out.println(2+" "+part2+" "+part1);
}
else {
System.out.println(2+" "+part1+" "+part2);
}
}
//截线与四边形的端点一点或两点相交
else if(judge3==1||judge1==1||judge2==1||judge4==1)
{
// 1.先判断对角线情况
if(judge1==judge3)
{
part1=getArea(point3,point4,point5);
part2=getArea(point3,point5,point6);
}
else if(judge2==judge4)
{
part1=getArea(point3,point4,point6);
part2=getArea(point4,point5,point6);
}
//截线交点不是对顶点
else if(judge1==1) {
if(judge2==judge3)
{
part1=getArea(jiedian1,jiedian2,point6);
part2=totalArea-part1;
}
else if(judge3==judge4)
{
part1=getArea(jiedian1,jiedian2,point4);
part2=totalArea-part1;
}
else if(judge4==judge2)
{
part1=getArea(jiedian1,jiedian2,point5);
part2=totalArea-part1;
}
}
else if(judge2==1) {
if(judge1==judge3)
{
part1=getArea(jiedian1,jiedian2,point6);
part2=totalArea-part1;
}
else if(judge1==judge4)
{
part1=getArea(jiedian1,jiedian2,point5);
part2=totalArea-part1;
}
else if(judge3==judge4)
{
part1=getArea(jiedian1,jiedian2,point3);
part2=totalArea-part1;
}
}
else if(judge3==1) {
if(judge1==judge2)
{
part1=getArea(jiedian1,jiedian2,point6);
part2=totalArea-part1;
}
else if(judge1==judge4)
{
part1=getArea(jiedian1,jiedian2,point4);
part2=totalArea-part1;
}
else if(judge4==judge2)
{
part1=getArea(jiedian1,jiedian2,point3);
part2=totalArea-part1;
}
}
else if(judge4==1) {
if(judge1==judge2)
{
part1=getArea(jiedian1,jiedian2,point5);
part2=totalArea-part1;
}
else if(judge2==judge3)
{
part1=getArea(jiedian1,jiedian2,point3);
part2=totalArea-part1;
}
else if(judge1==judge3)
{
part1=getArea(jiedian1,jiedian2,point4);
}
}
part1=formats.rounding(part1);
part2=formats.rounding(part2);
if(part1>part2)
{
System.out.println(2+" "+part2+" "+part1);
}
else {
System.out.println(2+" "+part1+" "+part2);
}
}
}
}
}
class OutputFormats{
//保留三位小数加四舍五入
public double rounding(double num)
{
String str=String.valueOf(num);
String substring = str.substring(str.indexOf(".") + 1);
int str_len;
if(substring.length()>3)
{
str_len=3;
}else {
str_len=substring.length();
}
String formats="%."+str_len+"f";
String out=String.format(formats,num);
double res = Double.parseDouble(out);
return res;
}
}
类图如下:

SourceMonitor的代码分析图如下:


分析:
1.该题主要涉及对四边形以及三角形的多种计算问题,代码中可以穿插上一次作业的部分模块,例如计算四边形面积可以将四边形分成两个三角形,直接使用已有方法即可,获取四边形的边也可以使用上次的公用方法,只需要修改参数即可,相较于上次的困难开局,完成本次作业的基本设计较为容易。
2.由于我构建本题的时候缺乏对提高代码复用性的计划,导致我在这道题目中本该使用继承和多态的地方没有实现功能。同时Line类中没有增加Point类作为属性,这就导致每次我使用Line类时无法使用构造函数一步到位地获取线的全部属性,例如长度,直线一般方程的A、B、C等,这使得我的代码冗余度比较高,除此之外还出现了为了实现一个功能写一个方法的情况,例如判断点是否在直线上写了包含端点的情况和不包含端点的情况。综上所述我认为虽然这道题我能通过,但就本次作业而言,该题代码质量不容乐观。
3.分析类图可也可以看出程序的依赖关系相当复杂,类与类之间的关系有待优化。
4.分析代码分析图可得,该代码的最高圈复杂度不在理想区间之内,我认这个应该归咎于我前期较为混乱的框架设计,好在我意识到了这种情况,并在下一次作业中实现了改进。
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()方法。
输入格式:
输入开户需要的姓名、密码
输入正确密码、存款金额
输入错误密码、取款金额
输入正确密码、大于余额的取款金额
输入正确密码、小于余额的取款金额
输出格式:
中国银行(银行名称)欢迎您的到来!
您的余额有多少元。
您的密码错误!
您的余额不足!
请取走钞票,您的余额还有多少元。
请收好您的证件和物品,欢迎您下次光临!
输入样例:
在这里给出一组输入。请注意,输入与输出是交替的,具体顺序请看测试类中的说明。例如:
张三 123456
123456 1000
654321 2000
123456 2000
123456 500
输出样例:
在这里给出相应的输出。请注意,输入与输出是交替的,具体顺序请看测试类中的说明。例如:
中国银行欢迎您的到来!
您的余额有1000.0元。
您的密码错误!
您的余额不足!
请取走钞票,您的余额还有500.0元。
请收好您的证件和物品,欢迎您下次光临!
源码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
BankBusiness ba=new BankBusiness();
ba.welecome();
Scanner sc=new Scanner(System.in);
String name = sc.next();
String password = sc.next();
BankBusiness a=new BankBusiness(name,password);
String password1 = sc.next();
String money=sc.nextLine();
a.deposit(password1, Double.parseDouble(money));
String password2 = sc.next();
String money2=sc.nextLine();
a.withdraw(password2, Double.parseDouble(money2));
String password3 = sc.next();
String money3=sc.nextLine();
a.withdraw(password3, Double.parseDouble(money3));
String password4 = sc.next();
String money4=sc.next();
a.withdraw(password4, Double.parseDouble(money4));
a.welcomeNext();
}
}
class BankBusiness {
public static String bankName ="中国银行";
private String name;
private String password;
private String getName() {
return name;
}
public BankBusiness() {
}
public BankBusiness(String name, String password) {
this.name = name;
this.password = password;
this.balance=0;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public double getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
private double balance=0;
//存款
public void deposit(String password,double money)
{
if(!password.equals(this.password))
{
System.out.println("您的密码错误!");
}
else {
this.balance+=money;
System.out.println("您的余额有"+this.balance+"元。");
}
}
public void withdraw(String password,double money)
{
if(!password.equals(this.password))
{
System.out.println("您的密码错误!");
}
else {
if(money>this.balance)
{
System.out.println("您的余额不足!");
}
else {
this.balance-=money;
System.out.println("请取走钞票,您的余额还有"+this.balance+"元。");
}
}
}
public void welecome()
{
System.out.println(bankName+"欢迎您的到来!");
}
public void welcomeNext()
{
System.out.println("请收好您的证件和物品,欢迎您下次光临!");
}
}
类图如下:

SourceMonitor的代码分析图如下:


分析:
1.本题主要考察java的私有属性与构造方法的创建,具体的输入输出参照题目要求即可,难度较低。
2.分析类图可得,该程序主要分为Main和bankBussiness类,主要是Main类中生成bankBusiness类的对象并传入相关参数,结构简单。
3.分析代码分析图可得,该程序的圈复杂度和深度均处于最佳区间内,程序冗余度低,程序复用性较好。
第五次作业
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
源码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String s = sc.nextLine();
Judge judge=new Judge();
boolean b = judge.JudgeFormat(s);
if(!b)
{
return;
}
Switchs sw=new Switchs();
sw.choose(s);
}
}
class situation1{
Judge judge=new Judge();
GetPoint gets=new GetPoint();
public void handle(String s)
{
boolean b = judge.Judge_num(1,s);
if(!b)
{
System.out.println("wrong number of points");
return;
}
List<Point> locations = gets.getLocations(s);
boolean b1 = judge.Judge_pentagon(locations);
if (b1)
{
System.out.println(true);
}
else {
System.out.println(false);
}
}
}
class situation2{
Line line=new Line();
Judge judge=new Judge();
GetPoint gets=new GetPoint();
Area area=new Area();
OutputFormats out=new OutputFormats();
public void handle(String s)
{
boolean b = judge.Judge_num(2,s);
if(!b)
{
System.out.println("wrong number of points");
return;
}
List<Point> locations = gets.getLocations(s);
boolean b1 = judge.Judge_pentagon(locations);
if(!b1)
{
System.out.println("not a pentagon");
return;
}
Point point1,point2,point3,point4,point5;
point1=locations.get(0);
point2=locations.get(1);
point3=locations.get(2);
point4=locations.get(3);
point5=locations.get(4);
double totalarea1 = area.getArea(point1, point2, point3) + area.getArea(point1, point3, point4) + area.getArea(point1, point4, point5);
double totalarea2 = area.getArea(point1, point2, point5) + area.getArea(point5, point2, point4) + area.getArea(point4, point2, point3);
double totalarea3 = area.getArea(point1, point2, point3) + area.getArea(point1, point3, point5) + area.getArea(point5, point3, point4);
double totalarea4= area.getArea(point2, point3, point4) + area.getArea(point1, point2, point4) + area.getArea(point1, point4, point5);
double totalarea5 = area.getArea(point1, point2, point5) + area.getArea(point2, point3, point5) + area.getArea(point3, point4, point5);
if(Math.abs(totalarea1-totalarea2)<0.01&&Math.abs(totalarea1-totalarea3)<0.01&&Math.abs(totalarea1-totalarea4)<0.01&&Math.abs(totalarea1-totalarea5)<0.01)
{
double finaArea=totalarea1;
double length = line.getLength(point1, point2);
double length1 = line.getLength(point2, point3);
double length2 = line.getLength(point3, point4);
double length3 = line.getLength(point4, point5);
double length4 = line.getLength(point5, point1);
double finaLength=length1+length2+length3+length4+length;
finaLength=out.rounding(finaLength);
finaArea=out.rounding(finaArea);
System.out.println(true+" "+finaLength+" "+finaArea);
}else {
System.out.println(false);
}
}
}
class situation3{
Judge judge=new Judge();
GetPoint gets=new GetPoint();
Remaining_points remaining_points=new Remaining_points();
public void handle(String s)
{
boolean b = judge.Judge_num(3,s);
if(!b)
{
System.out.println("wrong number of points");
}
List<Point> locations = gets.getLocations(s);
List<Point> resultList=new ArrayList<>();
Point point1,point2;
point1=locations.get(0);
point2=locations.get(1);
if(point1.getX()==point2.getX()&&point1.getY()==point2.getY())
{
System.out.println("points coincide");
return;
}
//将后五点存入数组中
resultList.add(locations.get(2));
resultList.add(locations.get(3));
resultList.add(locations.get(4));
resultList.add(locations.get(5));
resultList.add(locations.get(6));
//去重
resultList = judge.Delete_Duplicates(resultList);
//根据去重后点数分别判断
//如果依然是剩下5个点
if(resultList.size()==5)
{
remaining_points.remain5(point1,point2,resultList);
}
else if(resultList.size()==4)
{
remaining_points.remain4(point1,point2,resultList);
}
else if(resultList.size()==3)
{
remaining_points.remain3(point1,point2,resultList);
}
else {
System.out.println("not a polygon");
return;
}
}
}
class Switchs{
public void choose(String s)
{
int i = s.charAt(0) - '0';
switch (i)
{
case 1:{
situation1 situation1=new situation1();
situation1.handle(s);
break;
}
case 2:{
situation2 situation2=new situation2();
situation2.handle(s);
break;
}
case 3:{
situation3 situation3=new situation3();
situation3.handle(s);
break;
}
}
}
}
class GetPoint{
public List<Point> getLocations(String s)
{
List<Point> list=new ArrayList<>();
String splits =null;
splits=s.split(":")[1];
String[] s2 = splits.split(" ");
for (String split : s2) {
String[] split1 = split.split(",");
double x = Double.parseDouble(split1[0]);
double y = Double.parseDouble(split1[1]);
Point point=new Point();
point.setX(x);
point.setY(y);
list.add(point);
}
return list;
}
}
class Area {
Line line = new Line();
Judge judge = new Judge();
//获得指定三点组成三角形的面积
public double getArea(Point point1, Point point2, Point point3) {
double length1 = line.getLength(point1, point2);
double length2 = line.getLength(point2, point3);
double length3 = line.getLength(point1, point3);
double len = length1 + length2 + length3;
double p = len / 2;
//获得面积
double era = Math.pow((p * (p - length1) * (p - length2) * (p - length3)), 0.5);
return era;
}
public void getTriangular_sectional_area(List<Point> list)
{
Point point1 = list.get(0); Point point2 = list.get(1); Point point3 = list.get(2); Point point4 = list.get(3); Point point5 = list.get(4);
int collinear = judge.Collinear(point3,point4,point5);
//说明共线,不符合三角形,退出。
if (collinear == 1) {
System.out.println("not a polygon");
return;
}
//判断直线是否与三角形三个点中的两个点共线
int collinear5 = judge.Collinear(point1, point2, point3);
int collinear6 = judge.Collinear(point1, point2, point4);
int collinear7 = judge.Collinear(point1, point2, point5);
if (collinear5 == 1 && collinear6 == 1 || collinear6 == 1 && collinear7 == 1 ||collinear5==1&&collinear7==1 ) {
System.out.println("The line is coincide with one of the lines");
return;
}
Point p1 = line.intersection(point1, point2, point3, point4);
Point p2 = line.intersection(point1, point2, point3, point5);
Point p3 = line.intersection(point1, point2, point4, point5);
List<Point> in4=new ArrayList<>(); List<Point> in5=new ArrayList<>();
//将得到的坐标去重,符合在线段中的加入list表,返回值为in4
in4.addAll(Arrays.asList(p1,p2,p3));
in4=judge.Delete_Duplicates(in4);
for (Point point : in4) {
boolean b = judge.confirm_inlcude(point, point3, point4);
boolean b1 = judge.confirm_inlcude(point, point4, point5);
boolean b2 = judge.confirm_inlcude(point, point5, point3);
if(b||b1||b2)
{
in5.add(point);
}
}
if(in5.size()<2)
{
System.out.println(in5.size());
return;
}
//两交点的情况0
if(in5.size()==2){
Point po1 = in5.get(0);
Point po2 = in5.get(1);
double era1 = 0;
if(judge.confirm_inlcude(po1,point3,point4)&&judge.confirm_inlcude(po2,point4,point5))
{
era1=getArea(po1,po2,point4);
}
else if(judge.confirm_inlcude(po1,point4,point5)&&judge.confirm_inlcude(po2,point5,point3))
{
era1=getArea(po1,po2,point5);
}
else if(judge.confirm_inlcude(po1,point4,point3)&&judge.confirm_inlcude(po2,point3,point5))
{
era1=getArea(po1,po2,point3);
}
double area=getArea(point3,point4,point5);
double era2 = area - era1;
OutputFormats formats=new OutputFormats();
era1 = formats.rounding(era1);
era2 = formats.rounding(era2);
if(era2>era1)
{
System.out.println(2+" "+era1+" "+era2);
}
else{
System.out.println(2+" "+era2+" "+era1);
}
}
}
public void Quadrilateral_sectional_area(List<Point> list)
{
OutputFormats formats=new OutputFormats();
// 1.直线与四边形四边交点,比较是否在线段内,
//获得6个具体点
Point point1 = list.get(0); Point point2 = list.get(1); Point point3 = list.get(2); Point point4 = list.get(3); Point point5 = list.get(4); Point point6 = list.get(5);
Point p1 = line.intersection(point1, point2, point3, point4); Point p2 = line.intersection(point1, point2, point4, point5);
Point p3 = line.intersection(point1, point2, point5, point6); Point p4 = line.intersection(point1, point2, point6, point3);
List<Point> in5=new ArrayList<>(); List<Point> in6=new ArrayList<>();
//判断交点是否在四边形边上
in5.addAll(Arrays.asList(p1,p2,p3,p4));
in5=judge.Delete_Duplicates(in5);
for (Point point : in5) {
boolean b = judge.confirm_inlcude(point, point3, point4);
boolean b1 = judge.confirm_inlcude(point, point4, point5);
boolean b2 = judge.confirm_inlcude(point, point5, point6);
boolean b3 = judge.confirm_inlcude(point, point6, point3);
if(b||b1||b2||b3)
{
in6.add(point);
}
}
if(in6.size()<2)
{
System.out.println(in6.size());
return;
}
//两交点的情况0
if(in6.size()==2){
Point po1 = in6.get(0);
Point po2 = in6.get(1);
double era1 = 0;
if(judge.confirm_inlcude(po1,point3,point4)&&judge.confirm_inlcude(po2,point4,point5))
{
era1=getArea(po1,po2,point4);
}
else if(judge.confirm_inlcude(po1,point4,point5)&&judge.confirm_inlcude(po2,point5,point6))
{
era1=getArea(po1,po2,point5);
}
else if(judge.confirm_inlcude(po1,point5,point6)&&judge.confirm_inlcude(po2,point6,point3))
{
era1=getArea(po1,po2,point6);
}
else if(judge.confirm_inlcude(po1,point6,point3)&&judge.confirm_inlcude(po2,point3,point4))
{
era1=getArea(po1,po2,point3);
}
else if(judge.confirm_inlcude(po1,point3,point4)&&judge.confirm_inlcude(po2,point5,point6))
{
era1=(getArea(po1,po2,point4)+getArea(po1,po2,point5)+getArea(point4,point5,po1)+getArea(point4,point5,po2))/2;
}
else if(judge.confirm_inlcude(po1,point4,point5)&&judge.confirm_inlcude(po2,point6,point3))
{
era1=(getArea(po1,po2,point5)+getArea(po1,po2,point6)+getArea(point5,point6,po1)+getArea(point5,point6,po2))/2;
}
double era=getArea(point3,point4,point5)+getArea(point3,point6,point5);
double era2=era-era1;
era1 = formats.rounding(era1);
era2 = formats.rounding(era2);
if(era2>era1)
{
System.out.println(2+" "+era1+" "+era2);
}
else{
System.out.println(2+" "+era2+" "+era1);
}
}
}
public void Pentagon_intercept_area(List<Point> list)
{
OutputFormats formats=new OutputFormats();
// 1.直线与四边形四边交点,比较是否在线段内,
//获得6个具体点
Point point1 = list.get(0); Point point2 = list.get(1); Point point3 = list.get(2); Point point4 = list.get(3); Point point5 = list.get(4); Point point6 = list.get(5); Point point7=list.get(6);
Point p1 = line.intersection(point1, point2, point3, point4); Point p2 = line.intersection(point1, point2, point4, point5);
Point p3 = line.intersection(point1, point2, point5, point6); Point p4 = line.intersection(point1, point2, point6, point7);
Point p5 = line.intersection(point1, point2, point7, point3);
List<Point> in5=new ArrayList<>(); List<Point> in6=new ArrayList<>();
in5.addAll(Arrays.asList(p1,p2,p3,p4,p5));
in5=judge.Delete_Duplicates(in5);
for (Point point : in5) {
boolean b = judge.confirm_inlcude(point, point3, point4);
boolean b1 = judge.confirm_inlcude(point, point4, point5);
boolean b2 = judge.confirm_inlcude(point, point5, point6);
boolean b3 = judge.confirm_inlcude(point, point6, point7);
boolean b4 = judge.confirm_inlcude(point, point7, point3);
if(b||b1||b2||b3||b4)
{
in6.add(point);
}
}
if(in6.size()<2)
{
System.out.println(in6.size());
return;
}
else if(in6.size()==2)
{
Point po1 = in6.get(0);
Point po2 = in6.get(1);
double era1 = 0;
double totalera=getArea(point3,point4,point5)+getArea(point3,point5,point6)+getArea(point3,point6,point7);
if(judge.confirm_inlcude(po1,point3,point4)&&judge.confirm_inlcude(po2,point4,point5))
{
era1=getArea(po1,po2,point4);
}
else if(judge.confirm_inlcude(po1,point4,point5)&&judge.confirm_inlcude(po2,point5,point6))
{
era1=getArea(po1,po2,point5);
}
else if(judge.confirm_inlcude(po1,point5,point6)&&judge.confirm_inlcude(po2,point6,point7))
{
era1=getArea(po1,po2,point6);
}
else if(judge.confirm_inlcude(po1,point6,point7)&&judge.confirm_inlcude(po2,point7,point3))
{
era1=getArea(po1,po2,point7);
}
else if(judge.confirm_inlcude(po1,point7,point3)&&judge.confirm_inlcude(po2,point3,point4))
{
era1=getArea(po1,po2,point3);
}
else if(judge.confirm_inlcude(po1,point3,point4)&&judge.confirm_inlcude(po2,point5,point6))
{
era1=(getArea(po1,po2,point4)+getArea(po1,po2,point5)+getArea(point4,point5,po1)+getArea(point4,point5,po2))/2;
}
else if(judge.confirm_inlcude(po1,point4,point5)&&judge.confirm_inlcude(po2,point6,point7))
{
era1=(getArea(po1,po2,point5)+getArea(po1,po2,point6)+getArea(point5,point6,po1)+getArea(point5,point6,po2))/2;
}
else if(judge.confirm_inlcude(po1,point5,point6)&&judge.confirm_inlcude(po2,point7,point3))
{
era1=(getArea(po1,po2,point6)+getArea(po1,po2,point7)+getArea(point6,point7,po1)+getArea(point6,point7,po2))/2;
}
else if(judge.confirm_inlcude(po1,point6,point7)&&judge.confirm_inlcude(po2,point3,point4))
{
era1=(getArea(po1,po2,point7)+getArea(po1,po2,point3)+getArea(point7,point3,po1)+getArea(point7,point3,po2))/2;
}
else if(judge.confirm_inlcude(po1,point7,point3)&&judge.confirm_inlcude(po2,point4,point5))
{
era1=(getArea(po1,po2,point3)+getArea(po1,po2,point4)+getArea(point3,point4,po1)+getArea(point3,point4,po2))/2;
}
double era2=totalera-era1;
era1 = formats.rounding(era1);
era2 = formats.rounding(era2);
if(era2>era1)
{
System.out.println(2+" "+era1+" "+era2);
}
else{
System.out.println(2+" "+era2+" "+era1);
}
}
}
}
class Line{
//获取两点距离
public double getLength(Point po1,Point po2)
{
double x1=po1.getX();
double y1=po1.getY();
double x2=po2.getX();
double y2=po2.getY();
return Math.sqrt(Math.pow((x1-x2),2)+Math.pow((y1-y2),2));
}
//获取两直线交点
public Point intersection(Point point1,Point point2,Point point3,Point point4)
{
double x1,x2,x3,x4,y1,y2,y3,y4;
x1=point1.getX();
y1=point1.getY();
x2=point2.getX();
y2=point2.getY();
x3=point3.getX();
y3=point3.getY();
x4=point4.getX();
y4=point4.getY();
Point p=new Point();
double A1,B1,C1,A2,B2,C2;
A1 = y2-y1;
B1 = x1-x2;
C1 = x2*y1 -x1*y2;
A2 = y4-y3;
B2 = x3-x4;
C2 = x4*y3-x3*y4;
if(A1*B2-A2*B1==0)
{
double x=999898;
double y=478478;
p.setX(x);
p.setY(y);
return p;
}
double x =((B2*C1-B1*C2) / (A2*B1-A1*B2));
double y =((A1*C2-A2*C1) / (A2*B1-A1*B2));
p.setX(x);
p.setY(y);
return p;
}
//判断两直线交点是否在线段内
public boolean inline(Point point1,Point point2,Point point3,Point point4)
{
Point p = intersection(point1, point2, point3, point4);
Double x = p.getX();
Double y =p.getY();
Point po=new Point();
po.setX(x);
po.setY(y);
Judge judge=new Judge();
if(judge.confirm(po,point1,point2)&& judge.confirm(po,point3,point4))
{
return true;
}
else {
return false;
}
}
}
class Point{
private double x;
private double y;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}
class Judge{
//判断是否构成五边形
public boolean Judge_pentagon(List<Point> locations)
{
Line line=new Line();
Point point1 = locations.get(0);
Point point2 = locations.get(1);
Point point3 = locations.get(2);
Point point4 = locations.get(3);
Point point5 = locations.get(4);
boolean res1= line.inline(point1, point2, point3, point4);
boolean res2 = line.inline(point2, point3, point4, point5);
boolean res3 = line.inline(point3,point4,point1,point5);
boolean res4 = line.inline(point4,point5,point1,point2);
boolean res5 = line.inline(point5,point1,point2,point3);
int res6 = Collinear(point1, point2, point3);
int res7 = Collinear(point2, point3, point4);
int res8 = Collinear(point3, point4, point5);
int res9 = Collinear(point4, point5, point1);
int res10 = Collinear(point5, point1, point2);
if(res6==1||res7==1||res8==1||res9==1||res10==1)
{
return false;
}
else {
if(res1||res2||res3||res4||res5)
{
return false;
}
else {
return true;
}
}
}
//判断四边形
public boolean Judge_quadrangle(List<Point> locations)
{
Line line=new Line();
Point point1 = locations.get(0);
Point point2 = locations.get(1);
Point point3 = locations.get(2);
Point point4 = locations.get(3);
boolean res1= line.inline(point1, point2, point3, point4);
boolean res2 = line.inline(point2, point3, point4, point1);
int res3 = Collinear(point1, point2, point3);
int res4 = Collinear(point2, point3, point4);
int res5 = Collinear(point3, point4, point1);
int res6 = Collinear(point4, point1, point2);
if(res3==1||res4==1||res5==1||res6==1)
{
return false;
}
else {
if(res1||res2)
{
return false;
}
else {
return true;
}
}
}
//判断三角形
public boolean Judge_triangle(List<Point> resultList)
{
Point trianglePoint1 = resultList.get(0);
Point trianglePoint2 = resultList.get(1);
Point trianglePoint3 = resultList.get(2);
int collinear = Collinear(trianglePoint1, trianglePoint2, trianglePoint3);
if(collinear==1)
{
return false;
}
else {
return true;
}
}
//判断三点是否共线
public int Collinear(Point point1,Point point2,Point point3){
double x1, x2, x3,y1,y2,y3;
x1=point1.getX();
x2=point2.getX();
x3=point3.getX();
y1=point1.getY();
y2=point2.getY();
y3=point3.getY();
double k1,b1,c1;
k1 = y2-y1;
b1 = x1-x2;
c1 = x2*y1-x1*y2;
if(k1*x3+b1*y3+c1==0){
return 1;
}
else{
if(k1*x3+b1*y3+c1<0){
return -1;
}
else{
return 0;
}
}
}
public boolean Judge_num(int num,String s)
{
String s1 = s.split(":")[1];
String[] s2 = s1.split(" ");
switch (num)
{
case 1:
case 2:
{
if(s2.length!=5)
{
return false;
}
break;
}
case 3:{
if(s2.length!=7)
{
return false;
}
}
}
return true;
}
public boolean JudgeFormat(String s)
{
if(s.length()<=2)
{
System.out.println("Wrong Format");
return false;
}
char cc = s.charAt(0);
int i=cc-'0';
if(!(i<=5&&i>=1))
{
System.out.println("Wrong Format");
return false;
}
if(s.charAt(1)!=':')
{
System.out.println("Wrong Format");
return false;
}
String s1 = s.split(":")[1];
String[] s2 = s1.split(" ");
for (String s3 : s2) {
String[] split = s3.split(",");
if (split.length!=2)
{
System.out.println("Wrong Format");
return false;
}
for (String s4 : split) {
if(!s4.matches("^[+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?)"))
{
System.out.println("Wrong Format");
return false;
}
}
}
return true;
}
//数组去重方法,返回去重后的数组
public List<Point> Delete_Duplicates(List<Point> list)
{
List<Point> res =new ArrayList<>();
for (int i=0;i<list.size();i++)
{
int flag=0;
for(int j=0;j<res.size();j++)
{
if(list.get(i).getX()==res.get(j).getX()&&list.get(i).getY()==res.get(j).getY())
{
flag=1;
break;
}
}
if(flag==0)
{
res.add(list.get(i));
}
}
return res;
}
public boolean confirm(Point inter,Point point2,Point point3)
{
double x= inter.getX();
double y= inter.getY();
double x1,x2,y1,y2;
x1=point2.getX();
x2=point3.getX();
y1=point2.getY();
y2=point3.getY();
if(((x-x1)*(x-x2))<0||((y-y1)*(y-y2))<0)
{
return true;
}
else
{
return false;
}
}
public boolean confirm_inlcude(Point inter,Point point2,Point point3)
{
double x= inter.getX();
double y= inter.getY();
double x1,x2,y1,y2;
int c = Collinear(point2, point3, inter);
if(c!=1)
{
return false;
}
x1=point2.getX();y1=point2.getY();
x2=point3.getX();y2=point3.getY();
if(((x-x1)*(x-x2))<=0&&((y-y1)*(y-y2))<=0)
{
return true;
}
else
{
return false;
}
}
}
class OutputFormats{
//保留三位小数加四舍五入
public double rounding(double num)
{
String str=String.valueOf(num);
String substring = str.substring(str.indexOf(".") + 1);
int str_len;
if(substring.length()>3)
{
str_len=3;
}else {
str_len=substring.length();
}
String formats="%."+str_len+"f";
String out=String.format(formats,num);
double res = Double.parseDouble(out);
return res;
}
}
class Remaining_points{
Area area= new Area();
Judge judge=new Judge();
public void remain5(Point point1,Point point2,List<Point> resultList)
{
List<Point> temp=new ArrayList<>();
boolean b1 = judge.Judge_pentagon(resultList);
Point point3,point4,point5,point6,point7;
point3=resultList.get(0);
point4=resultList.get(1);
point5=resultList.get(2);
point6=resultList.get(3);
point7=resultList.get(4);
//说明是凸五边形
if(b1)
{
int collinear1 = judge.Collinear(point1, point2, point3);
int collinear2 = judge.Collinear(point1, point2, point4);
int collinear3 = judge.Collinear(point1, point2, point5);
int collinear4 = judge.Collinear(point1, point2, point6);
int collinear5 = judge.Collinear(point1, point2, point7);
if (collinear1 == 1 && collinear2 == 1 || collinear2 == 1 && collinear3 == 1 || collinear3 == 1 && collinear4 == 1|| collinear4 == 1 && collinear5 == 1||collinear5 == 1 && collinear1 == 1) {
System.out.println("The line is coincide with one of the lines");
return;
}
List<Point> temps=new ArrayList<>();
// System.out.println("是凸五边形");
temps.addAll(Arrays.asList(point1,point2,point3,point4,point5,point6,point7));
area.Pentagon_intercept_area(temps);
}
//不是五边形,判断是否是四边形或者三角形,要去掉在边上的点
else {
int collinear1 = judge.Collinear(point3, point5, point4);
int collinear2 = judge.Collinear(point4, point6, point5);
int collinear3 = judge.Collinear(point5, point7, point6);
int collinear4 = judge.Collinear(point6, point3, point7);
int collinear5 = judge.Collinear(point7, point4, point3);
boolean confirm1 = judge.confirm(point4, point3, point5);
boolean confirm2 = judge.confirm(point5, point4, point6);
boolean confirm3 = judge.confirm(point6, point5, point7);
boolean confirm4 = judge.confirm(point7, point6, point3);
boolean confirm5 = judge.confirm(point3, point7, point4);
if(collinear1==1||collinear2==1||collinear3==1||collinear4==1||collinear5==1)
{
if(collinear1==1&&confirm1)
{
temp.addAll(Arrays.asList(point3,point5,point6,point7));
remain4(point1,point2,temp);
}
else if(collinear2==1&&confirm2)
{
temp.addAll(Arrays.asList(point3,point4,point6,point7));
remain4(point1,point2,temp);
}
else if(collinear3==1&&confirm3)
{
temp.addAll(Arrays.asList(point3,point4,point5,point7));
remain4(point1,point2,temp);
}
else if(collinear4==1&&confirm4)
{
temp.addAll(Arrays.asList(point3,point4,point5,point6));
remain4(point1,point2,temp);
}
else if(collinear5==1&&confirm5)
{
temp.addAll(Arrays.asList(point4,point5,point6,point7));
remain4(point1,point2,temp);
}
} else {
System.out.println("not a polygon");
}
}
}
public void remain4(Point point1,Point point2,List<Point> resultList)
{
List<Point> temps=new ArrayList<>();
List<Point> tempss=new ArrayList<>();
Point point3,point4,point5,point6;
point3=resultList.get(0);
point4=resultList.get(1);
point5=resultList.get(2);
point6=resultList.get(3);
tempss.addAll(Arrays.asList(point3,point4,point5,point6));
boolean yes = judge.Judge_quadrangle(tempss);
//如果能组成四边形
if(yes)
{
int collinear1 = judge.Collinear(point1, point2, point3);
int collinear2 = judge.Collinear(point1, point2, point4);
int collinear3 = judge.Collinear(point1, point2, point5);
int collinear4 = judge.Collinear(point1, point2, point6);
if (collinear1 == 1 && collinear2 == 1 || collinear2 == 1 && collinear3 == 1 || collinear3 == 1 && collinear4 == 1|| collinear4 == 1 && collinear1 == 1) {
System.out.println("The line is coincide with one of the lines");
return;
}
//具体判断截线与边的情况
temps.addAll(Arrays.asList(point1,point2,point3,point4,point5,point6));
area.Quadrilateral_sectional_area(temps);
}
//如果四点不能组成四边形,判断是否组成三角形
else {
int collinear1 = judge.Collinear(point3, point5, point4);
int collinear2 = judge.Collinear(point4, point6, point5);
int collinear3 = judge.Collinear(point5, point3, point6);
int collinear4 = judge.Collinear(point6, point4, point3);
boolean confirm1 = judge.confirm(point4, point3, point5);
boolean confirm2 = judge.confirm(point5, point4, point6);
boolean confirm3 = judge.confirm(point6, point5, point3);
boolean confirm4 = judge.confirm(point3, point6, point4);
if(collinear1==1||collinear2==1||collinear3==1||collinear4==1)
{
if(collinear1==1&&confirm1)
{
temps.addAll(Arrays.asList(point1,point2,point3,point5,point6));
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
else if(collinear2==1&&confirm2)
{
temps.addAll(Arrays.asList(point1,point2,point3,point4,point6));
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
else if(collinear3==1&&confirm3)
{
temps.addAll(Arrays.asList(point1,point2,point3,point4,point5));
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
else if(collinear4==1&&confirm4)
{
temps.addAll(Arrays.asList(point1,point2,point4,point5,point6));
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
else {
System.out.println("not a polygon");
}
}
else {
System.out.println("not a polygon");
}
}
}
public void remain3(Point point1,Point point2,List<Point> resultList)
{
List<Point> temps=new ArrayList<>();
Point trianglePoint1 = resultList.get(0);
Point trianglePoint2 = resultList.get(1);
Point trianglePoint3 = resultList.get(2);
boolean b1 = judge.Judge_triangle(resultList);
if(!b1)
{
System.out.println("not a polygon");
return;
}
//判断直线与三角形位置,如果三角形两端点与直线共线,则输出错误信息
int collinear1 = judge.Collinear(point1, point2, trianglePoint1);
int collinear2 = judge.Collinear(point1, point2, trianglePoint2);
int collinear3 = judge.Collinear(point1, point2, trianglePoint3);
if (collinear1 == 1 && collinear2 == 1 || collinear1 == 1 && collinear3 == 1 || collinear2 == 1 && collinear3 == 1) {
System.out.println("The line is coincide with one of the lines");
return;
}
//否则说明直线与三角形边不重合,开始判断直线与三角形截线关系,可调参
else {
temps.addAll(Arrays.asList(point1,point2,resultList.get(0),resultList.get(1),resultList.get(2)));
//截线与三角形面积的关系
area.getTriangular_sectional_area(temps);
}
}
}
类图如下:

SourceMonitor的代码分析图如下:


分析:
1.本题实现的是前三问,主要涉及五边形的判断,计算以及截面积的获取,主要实现方向与前两次作业类似,部分方法也得以沿用,在原来的基础上增加些许功能代码即可。
2.在这道题中我又犯了和第四次作业第二道题同样的错误,代码架构设计不清晰导致我实现某些方法时非常复杂且低效率,例如判断截线与多边形的相对位置的方法,我对每种情况进行穷举,导致if数量过多,第一次提交时直接超过50kb。这些设计上的失误使得我不得不重写许多代码,这也是本题的类图同样复杂难以理解的原因。万幸的是在第二题我修改了代码的基础架构,这些问题得到了一部分缓解。
3.分析代码分析图可得,由于我对题目的理解不到位,导致某些方法例如获取多边形面积,需要反复调用,这导致代码的平均深度和最大圈复杂度超过了期望值,同时方法设置较多,平均方法数也与期望值不符,虽然能够勉强通过全部测验,但是代码质量还需进一步改进。
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
源码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String s = sc.nextLine();
Judge judge=new Judge();
boolean b = judge.JudgeFormat(s);
if(!b)
{
return;
}
Switchs sw=new Switchs();
sw.choose(s);
}
}
//多边形类
class polygon{
public List<Point> sorts(List<Point> temp)
{
Point center = getCenter(temp);
Point p=new Point();
for(int i=1;i<temp.size();i++)
{
for(int j=0;j<temp.size()-i;j++)
{
if(PointCmp(temp.get(j),temp.get(j+1),center))
{
p.setX(temp.get(j).getX());
p.setY(temp.get(j).getY());
temp.get(j).setX(temp.get(j+1).getX());
temp.get(j).setY(temp.get(j+1).getY());
temp.get(j+1).setX(p.getX());
temp.get(j+1).setY(p.getY());
}
}
}
return temp;
}
//求内点
public Point getCenter(List<Point> temp)
{
// 多边形的顶点个数
int num =temp.size();
// 多边形的顶点求和
double X = 0, Y = 0;
for (int i = 0; i < num; i++) {
X += temp.get(i).getX();
Y += temp.get(i).getY();
}
double v = X / num;
double v1 = Y / num;
// 返回内点
Point center = new Point();
center.setX(v);
center.setY(v1);
return center;
}
public boolean PointCmp(Point pointA, Point pointB, Point center)
{
double det = (pointA.getX() - center.getX()) * (pointB.getY() - center.getY()) - (pointB.getX() - center.getX()) * (pointA.getY() - center.getY());
// 若OA在OB的顺时针方向,点A大于点B,按降序排列,则返回false
if (det > 0) {
return false;
}
else {
return true;
}
}
public double GetArea(List<Point> temp)
{
double res = 0;
Point po=temp.get(0);
for(int i=1;i<temp.size()-1;i++)
{
triangle tr=new triangle(po,temp.get(i),temp.get(i+1));
res+=tr.area;
}
return res;
}
}
class Switchs{
Judge judge=new Judge();
public void choose(String s)
{
Point point=new Point();
int i = s.charAt(0) - '0';
switch (i)
{
case 4:{
Output out=new Output();
boolean b = judge.Judge_num(4, s);
if(!b)
{
System.out.println("wrong number of points");
return;
}
List<Point> ls = point.getLocations(s);
List<Point> temp1=new ArrayList<>();List<Point> temp2=new ArrayList<>();
temp1.addAll(Arrays.asList(ls.get(0),ls.get(1),ls.get(2),ls.get(3),ls.get(4)));
temp2.addAll(Arrays.asList(ls.get(5),ls.get(6),ls.get(7),ls.get(8),ls.get(9)));
temp1=out.Delete_Duplicates(temp1);
temp2=out.Delete_Duplicates(temp2);
temp1=out.getFinalArray(temp1);
temp2=out.getFinalArray(temp2);
List<Integer> res1=new ArrayList<>();List<Integer> res2=new ArrayList<>();
String type1 = null,type2 = null;
if(temp1.size()==5)
{
type1="pentagon";
pentagon pa=new pentagon(temp1.get(0),temp1.get(1),temp1.get(2),temp1.get(3),temp1.get(4));
for(int j=0;j<temp2.size();j++)
{
res1.add(pa.inside(temp2.get(j)));
}
}
if(temp1.size()==4)
{
type1="quadrilateral";
quadrilateral q=new quadrilateral(temp1.get(0),temp1.get(1),temp1.get(2),temp1.get(3));
for(int j=0;j<temp2.size();j++)
{
res1.add(q.inside(temp2.get(j)));
}
}
if(temp1.size()==3)
{
type1 = "triangle";
triangle tr=new triangle(temp1.get(0),temp1.get(1),temp1.get(2));
for(int j=0;j<temp2.size();j++)
{
res1.add(tr.inside(temp2.get(j)));
}
}
if(temp2.size()==5)
{
type2="pentagon";
pentagon pa=new pentagon(temp2.get(0),temp2.get(1),temp2.get(2),temp2.get(3),temp2.get(4));
for(int j=0;j<temp1.size();j++)
{
res2.add(pa.inside(temp1.get(j)));
}
}
if(temp2.size()==4)
{
type2="quadrilateral";
quadrilateral q=new quadrilateral(temp2.get(0),temp2.get(1),temp2.get(2),temp2.get(3));
for(int j=0;j<temp1.size();j++)
{
res2.add(q.inside(temp1.get(j)));
}
}
if(temp2.size()==3)
{
type2 = "triangle";
triangle tr=new triangle(temp2.get(0),temp2.get(1),temp2.get(2));
for(int j=0;j<temp1.size();j++)
{
res2.add(tr.inside(temp1.get(j)));
}
}
//判断两个多边形交点数量
List<Point> res = judge.getnumber(temp1, temp2);
int in2=0,on2=0,outs2=0; int in1=0,on1=0,outs1=0;
for (Integer re : res1) {
if(re == 0)
{
on2++;
}
else if(re==1)
{
outs2++;
}
else {
in2++;
}
}
for (Integer re : res2) {
if(re == 0)
{
on1++;
}
else if(re==1)
{
outs1++;
}
else {
in1++;
}
}
//完全重合
if(on1==temp1.size()&&on2==temp2.size())
{
System.out.println("the previous "+type1+" coincides with the following "+type2);
}
//分离
else if(outs1==temp1.size()&&outs2==temp2.size())
{
System.out.println("no overlapping area between the previous "+type1+" and the following "+type2);
}
//被包含
else if(on2+in2==temp2.size()&&outs2==0)
{
System.out.println("the previous "+type1 +" contains the following "+type2);
}
//包含
else if(on1+in1==temp1.size()&&outs1==0)
{
System.out.println("the previous "+type1 +" is inside the following "+type2);
}
//连接
else if(res.size()<=2&&in1==0&&in2==0)
{
System.out.println("the previous "+type1+" is connected to the following "+type2);
}
//交错
else{
System.out.println("the previous "+type1+" is interlaced with the following "+type2);
}
break;
}
//基本思想,先获取交点和在两多边形互相里面的点去重,排序,最后调用area方法
case 5:{
Output out=new Output();
boolean b = judge.Judge_num(5, s);
if(!b)
{
System.out.println("wrong number of points");
return;
}
List<Point> ls = point.getLocations(s);
List<Point> temp1=new ArrayList<>();List<Point> temp2=new ArrayList<>();
temp1.addAll(Arrays.asList(ls.get(0),ls.get(1),ls.get(2),ls.get(3),ls.get(4)));
temp2.addAll(Arrays.asList(ls.get(5),ls.get(6),ls.get(7),ls.get(8),ls.get(9)));
temp1=out.Delete_Duplicates(temp1);
temp2=out.Delete_Duplicates(temp2);
temp1=out.getFinalArray(temp1);
temp2=out.getFinalArray(temp2);
List<Point> temp=new ArrayList<>();
if(temp1.size()==5)
{
pentagon pa=new pentagon(temp1.get(0),temp1.get(1),temp1.get(2),temp1.get(3),temp1.get(4));
for(int j=0;j<temp2.size();j++)
{
int inside = pa.inside(temp2.get(j));
if(inside==-1||inside==0)
{
temp.add(temp2.get(j));
}
}
}
if(temp1.size()==4)
{
quadrilateral q=new quadrilateral(temp1.get(0),temp1.get(1),temp1.get(2),temp1.get(3));
for(int j=0;j<temp2.size();j++)
{
int inside = q.inside(temp2.get(j));
if(inside==-1||inside==0)
{
temp.add(temp2.get(j));
}
}
}
if(temp1.size()==3)
{
triangle tr=new triangle(temp1.get(0),temp1.get(1),temp1.get(2));
for(int j=0;j<temp2.size();j++)
{
int inside = tr.inside(temp2.get(j));
if(inside==-1||inside==0)
{
temp.add(temp2.get(j));
}
}
}
if(temp2.size()==5)
{
pentagon pa=new pentagon(temp2.get(0),temp2.get(1),temp2.get(2),temp2.get(3),temp2.get(4));
for(int j=0;j<temp1.size();j++)
{
int inside = pa.inside(temp1.get(j));
if(inside==-1||inside==0)
{
temp.add(temp1.get(j));
}
}
}
if(temp2.size()==4)
{
quadrilateral q=new quadrilateral(temp2.get(0),temp2.get(1),temp2.get(2),temp2.get(3));
for(int j=0;j<temp1.size();j++)
{
int inside = q.inside(temp1.get(j));
if(inside==-1||inside==0)
{
temp.add(temp1.get(j));
}
}
}
if(temp2.size()==3)
{
triangle tr=new triangle(temp2.get(0),temp2.get(1),temp2.get(2));
for(int j=0;j<temp1.size();j++)
{
int inside = tr.inside(temp1.get(j));
if(inside==-1||inside==0)
{
temp.add(temp1.get(j));
}
}
}
List<Point> getnumber = judge.getnumber(temp1, temp2);
for (Point point1 : getnumber) {
temp.add(point1);
}
temp=out.Delete_Duplicates(temp);
//自此获得交点以及内点的数组,对其进行排序
polygon p=new polygon();
temp=p.sorts(temp);
double area= p.GetArea(temp);
// if(temp.size()==3)
// {
// triangle tr=new triangle(temp.get(0),temp.get(1),temp.get(2));
// area = tr.area;
// }
// else if(temp.size()==4)
// {
// quadrilateral q=new quadrilateral(temp.get(0),temp.get(1),temp.get(2),temp.get(3));
// area=q.area;
// }else if(temp.size()==5)
// {
// pentagon pa=new pentagon(temp.get(0),temp.get(1),temp.get(2),temp.get(3),temp.get(4));
// area=pa.area;
// }
area=out.rounding(area);
System.out.println(area);
break;
}
case 6:{
Output out=new Output();
boolean b = judge.Judge_num(6, s);
if(!b)
{
System.out.println("wrong number of points");
return;
}
List<Point> ls = point.getLocations(s);
List<Point> temp=new ArrayList<>();
//获取后五点
Point po1,po2,po3,po4,po5;
po1=ls.get(1); po2=ls.get(2); po3=ls.get(3); po4=ls.get(4); po5=ls.get(5);
temp.addAll(Arrays.asList(po1,po2,po3,po4,po5));
temp=out.Delete_Duplicates(temp);
temp= out.getFinalArray(temp);
if(temp.size()==5)
{
pentagon pa=new pentagon(po1,po2,po3,po4,po5);
int inside = pa.inside(ls.get(0));
if(inside==0)
{
System.out.println("on the pentagon");
}else if (inside==1)
{
System.out.println("outof the pentagon");
}
else if(inside==-1)
{
System.out.println("in the pentagon");
}
}
else if(temp.size()==4)
{
quadrilateral q=new quadrilateral(temp.get(0),temp.get(1),temp.get(2),temp.get(3));
int inside = q.inside(ls.get(0));
if(inside==0)
{
System.out.println("on the quadrilateral");
}else if (inside==1)
{
System.out.println("outof the quadrilateral");
}
else if(inside==-1)
{
System.out.println("in the quadrilateral");
}
}else if(temp.size()==3)
{
triangle tr=new triangle(temp.get(0),temp.get(1),temp.get(2));
int inside = tr.inside(ls.get(0));
if(inside==0)
{
System.out.println("on the triangle");
}else if(inside==-1)
{
System.out.println("in the triangle");
}
else {
System.out.println("outof the triangle");
}
}
}
}
}
}
//三角形类
class triangle extends polygon{
Line l1,l2,l3;
Double area;
Point p1,p2,p3;
public triangle() {}
public triangle(Point po1,Point po2,Point po3) {
this.l1 = new Line(po1,po2);
this.l2 = new Line(po2,po3);
this.l3 = new Line(po3,po1);
p1=po1;p2=po2;p3=po3;
this.area=getArea(l1,l2,l3);
}
//用第三个点是否与第一条直线共线判断能否组成三角形
public boolean Judge_triangle()
{
Line line=new Line();
int collinear = line.Collinear(l1,l2.p2);
if(collinear==1)
{
return false;
}
else {
return true;
}
}
public double getArea(Line l1,Line l2,Line l3) {
double len =l1.length+l2.length+l3.length;
double p = len / 2;
//获得面积
double era = Math.pow((p * (p - l1.length) * (p - l2.length) * (p - l3.length)), 0.5);
return era;
}
public int inside(Point p)
{
Line ll1=new Line(p,p1);Line ll2=new Line(p,p2);
Line ll3=new Line(p,p2);Line ll4=new Line(p,p3);
Line ll5=new Line(p,p3);Line ll6=new Line(p,p1);
double result = getArea(ll1, ll2, l1) + getArea(ll3, ll4, l2) + getArea(ll5, ll6, l3);
if(Math.abs(result-this.area)>0.01)
{
return 1;
} else
{
int c1 = l1.Collinear(p); int c2 = l2.Collinear(p); int c3 = l3.Collinear(p);
if(c1==1||c2==1||c3==1)
{
return 0;
}else {
return -1;
}
}
}
}
//四边形类
class quadrilateral extends triangle
{
Line l1,l2,l3,l4,l13,l24;
Point p1,p2,p3,p4;
double area;
//注意对角线
public quadrilateral(Point po1,Point po2,Point po3,Point po4){
this.l1 = new Line(po1,po2);
this.l2 = new Line(po2,po3);
this.l3 = new Line(po3,po4);
this.l4 = new Line(po4,po1);
p1=po1;p2=po2;p3=po3;p4=po4;
get_Opposite();
this.area=getArea(l1,l2,l13)+getArea(l3,l4,l13);
}
public void get_Opposite()
{
this.l13=new Line(p1,p3);
this.l24=new Line(p2,p4);
}
public quadrilateral() {}
//判断四边形
public boolean Judge_quadrangle()
{
Line line=new Line();
boolean res1= line.inline(l1,l3);
boolean res2 = line.inline(l2,l4);
int res3 =line.Collinear(l1, l2.p2);
int res4 = line.Collinear(l2, l3.p2);
int res5 = line.Collinear(l3, l4.p2);
int res6 =line.Collinear(l4, l1.p2);
if(res3==1||res4==1||res5==1||res6==1)
{
return false;
}
else {
if(res1||res2)
{
return false;
}
else {
return true;
}
}
}
public int inside(Point p) {
Line ll1=new Line(p,l1.p1);Line ll2=new Line(p,l1.p2);
Line ll3=new Line(p,l2.p1);Line ll4=new Line(p,l2.p2);
Line ll5=new Line(p,l3.p1);Line ll6=new Line(p,l3.p2);
Line ll7=new Line(p,l4.p1);Line ll8=new Line(p,l4.p2);
double result = getArea(ll1, ll2, l1) + getArea(ll3, ll4, l2) + getArea(ll5, ll6, l3)+getArea(ll7,ll8,l4);
if(Math.abs(result-this.area)>0.01)
{
return 1;
} else
{
int c1 = l1.Collinear(p); int c2 = l2.Collinear(p); int c3 = l3.Collinear(p);int c4=l4.Collinear(p);
if(c1==1||c2==1||c3==1||c4==1)
{
return 0;
}else {
return -1;
}
}
}
}
//五边形类
class pentagon extends quadrilateral{
Line l1,l2,l3,l4,l5;
Line l13,l14,l24,l35,l41,l52;
Point p1,p2,p3,p4,p5;
double area;
public pentagon(Point po1,Point po2,Point po3,Point po4,Point po5)
{
this.l1 = new Line(po1,po2);
this.l2 = new Line(po2,po3);
this.l3 = new Line(po3,po4);
this.l4 = new Line(po4,po5);
this.l5 = new Line(po5,po1);
p1=po1;p2=po2;p3=po3;p4=po4;p5=po5;
get_Opposite();
this.area=getArea(l1,l2,l13)+getArea(l13,l3,l14)+getArea(l14,l4,l5);
}
@Override
public void get_Opposite() {
this.l13=new Line(p1,p3);
this.l14=new Line(p1,p4);
this.l24=new Line(p2,p4);
this.l35=new Line(p3,p5);
this.l41=new Line(p4,p1);
this.l52=new Line(p5,p2);
}
//判断能否组成五边形
public boolean Judge_pentagon()
{
Line line=new Line();
boolean res1= line.inline(l1,l3);
boolean res2 = line.inline(l2,l4);
boolean res3 = line.inline(l3,l5);
boolean res4 = line.inline(l4,l1);
boolean res5 = line.inline(l5,l2);
int res6 = line.Collinear(l1, p3);
int res7 = line.Collinear(l2, p4);
int res8 = line.Collinear(l3, p5);
int res9 = line.Collinear(l4, p1);
int res10 = line.Collinear(l5,p2);
if(res6==1||res7==1||res8==1||res9==1||res10==1)
{
return false;
}
else {
if(res1||res2||res3||res4||res5)
{
return false;
}
else {
return true;
}
}
}
//判断点与五边形的位置关系
public int inside(Point p) {
Line ll1=new Line(p,l1.p1);Line ll2=new Line(p,l1.p2);
Line ll3=new Line(p,l2.p1);Line ll4=new Line(p,l2.p2);
Line ll5=new Line(p,l3.p1);Line ll6=new Line(p,l3.p2);
Line ll7=new Line(p,l4.p1);Line ll8=new Line(p,l4.p2);
Line ll9=new Line(p,l5.p1); Line ll10=new Line(p,l5.p2);
double result = getArea(ll1, ll2, l1) + getArea(ll3, ll4, l2) + getArea(ll5, ll6, l3)+getArea(ll7,ll8,l4)+getArea(ll9,ll10,l5);
if(Math.abs(result-this.area)>0.01)
{
return 1;
} else
{
int c1 = l1.Collinear(p); int c2 = l2.Collinear(p); int c3 = l3.Collinear(p);int c4=l4.Collinear(p);int c5=l5.Collinear(p);
if(c1==1||c2==1||c3==1||c4==1||c5==1)
{
return 0;
}else {
return -1;
}
}
}
}
//线类
class Line{
Point p1,p2;
double A,B,C;
double x1,x2,y1,y2;
double length;
public Line(Point p1, Point p2) {
this.p1=p1;
this.p2=p2;
x1=p1.getX(); y1=p1.getY();
x2=p2.getX(); y2=p2.getY();
this.A = y2-y1;
this.B = x1-x2;
this.C = x2*y1 -x1*y2;
this.length=Math.sqrt(Math.pow((x1-x2),2)+Math.pow((y1-y2),2));
}
public Line() {}
//获取两直线交点
public Point intersection(Line l1,Line l2)
{
Point p = new Point();
double A1,B1,C1,A2,B2,C2;
A1 = l1.A; B1 = l1.B; C1 = l1.C;
A2 = l2.A; B2 =l2.B;C2 = l2.C;
if(A1*B2-A2*B1==0)
{
double x=999898;
double y=478478;
p.setX(x);
p.setY(y);
return p;
}
double x =((B2*C1-B1*C2) / (A2*B1-A1*B2));
double y =((A1*C2-A2*C1) / (A2*B1-A1*B2));
p.setX(x); p.setY(y);
return p;
}
//判断两直线交点是否在线段内
public boolean inline(Line l1,Line l2)
{
Point p = intersection(l1,l2);
Double x = p.getX(); Double y =p.getY();
Point po=new Point();
po.setX(x);
po.setY(y);
if(confirm(po,l1)&& confirm(po,l2))
{
return true;
}
else {
return false;
}
}
// 判断共线
public int Collinear(Line l,Point point3){
double x3,y3;
x3=point3.getX();
y3=point3.getY();
if(l.A*x3+l.B*y3+l.C==0){
return 1;
}
else{
if(l.A*x3+l.B*y3+l.C<0){
return -1;
}
else{
return 0;
}
}
}
//重载
public int Collinear(Point point3){
double x3,y3;
x3=point3.getX();
y3=point3.getY();
if(A*x3+B*y3+C==0){
return 1;
}
else{
if(A*x3+B*y3+C<0){
return -1;
}
else{
return 0;
}
}
}
//判断点是否在线段内(不包含端点)
public boolean confirm(Point inter,Line l)
{
double x= inter.getX();
double y= inter.getY();
double x1,x2,y1,y2;
x1=l.p1.getX(); x2=l.p2.getX();
y1=l.p1.getY(); y2=l.p2.getY();
if(((x-x1)*(x-x2))<0||((y-y1)*(y-y2))<0)
{
return true;
}
else
{
return false;
}
}
//判断点是否在线段内(包含端点)
public boolean confirm_inlcude(Point inter,Line l)
{
double x= inter.getX();
double y= inter.getY();
double x1,x2,y1,y2;
x1=l.p1.getX();y1=l.p1.getY();
x2=l.p2.getX();y2=l.p2.getY();
if(((x-x1)*(x-x2))<=0&&((y-y1)*(y-y2))<=0)
{
return true;
}
else
{
return false;
}
}
}
//点类
class Point{
private double x;
private double y;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
public List<Point> getLocations(String s)
{
List<Point> list=new ArrayList<>();
String splits =null;
splits=s.split(":")[1];
String[] s2 = splits.split(" ");
for (String split : s2) {
String[] split1 = split.split(",");
double x = Double.parseDouble(split1[0]);
double y = Double.parseDouble(split1[1]);
Point point=new Point();
point.setX(x);
point.setY(y);
list.add(point);
}
return list;
}
}
class Judge{
public boolean Judge_num(int num,String s)
{
String s1 = s.split(":")[1];
String[] s2 = s1.split(" ");
switch (num)
{
case 4:
case 5:
{
if(s2.length!=10)
{
return false;
}
break;
}
case 6:{
if(s2.length!=6)
{
return false;
}
}
}
return true;
}
public boolean JudgeFormat(String s)
{
if(s.length()<=2)
{
System.out.println("Wrong Format");
return false;
}
char cc = s.charAt(0);
int i=cc-'0';
if((i!=4&&i!=5&&i!=6))
{
System.out.println("Wrong Format");
return false;
}
if(s.charAt(1)!=':')
{
System.out.println("Wrong Format");
return false;
}
String s1 = s.split(":")[1];
String[] s2 = s1.split(" ");
for (String s3 : s2) {
String[] split = s3.split(",");
if (split.length!=2)
{
System.out.println("Wrong Format");
return false;
}
for (String s4 : split) {
if(!s4.matches("^[+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?)"))
{
System.out.println("Wrong Format");
return false;
}
}
}
return true;
}
Line l=new Line();
public Point inline(Line l1,Line l2)
{
Point p = l.intersection(l1,l2);
Double x = p.getX(); Double y =p.getY();
Point po=new Point();
po.setX(x);
po.setY(y);
if(l.confirm_inlcude(po,l1)&&l.confirm_inlcude(po,l2))
{
return po;
}
else {
return null;
}
}
public List<Point> getnumber(List<Point> temp1,List<Point> temp2)
{
Output out=new Output();
List<Point> res=new ArrayList<>();
for(int p=0;p<temp1.size();p++)
{
Line l1=new Line(temp1.get(p),temp1.get((p+1)%temp1.size()));
for(int q=0;q<temp2.size();q++)
{
Line l2=new Line(temp2.get(q),temp2.get((q+1)%temp2.size()));
Point inline =inline(l1, l2);
if(inline!=null)
{
res.add(inline);
}
}
}
res=out.Delete_Duplicates(res);
return res;
}
}
class Output{
//保留三位小数加四舍五入
public double rounding(double num)
{
String str=String.valueOf(num);
String substring = str.substring(str.indexOf(".") + 1);
int str_len;
if(substring.length()>3)
{
str_len=3;
}else {
str_len=substring.length();
}
String formats="%."+str_len+"f";
String out=String.format(formats,num);
double res = Double.parseDouble(out);
return res;
}
//数组去重方法,返回去重后的数组
public List<Point> Delete_Duplicates(List<Point> list)
{
List<Point> res =new ArrayList<>();
for (int i=0;i<list.size();i++)
{
int flag=0;
for(int j=0;j<res.size();j++)
{
if(list.get(i).getX()==res.get(j).getX()&&list.get(i).getY()==res.get(j).getY())
{
flag=1;
break;
}
}
if(flag==0)
{
res.add(list.get(i));
}
}
return res;
}
//统一去除冗余点,获得最终结果
public List<Point> getFinalArray(List<Point> list)
{
for(int i=0;i<list.size();)
{
Line line=new Line(list.get(i),list.get((i+2)%list.size()));
if(line.Collinear(list.get((i+1)%list.size()))==1&& line.confirm(list.get((i+1)%list.size()), line))
{
list.remove(list.get((i+1)%list.size()));
i=0;
}
else {
i++;
}
}
return list;
}
}
类图如下:

SourceMonitor的代码分析图如下:


分析:
1.本题我重写了大部分代码架构,包括但不限于,修改Line的属性,增加Point对象以及一些Line独有的属性,增加三角形、四边形、五边形、多边形类,其中三角形继承多边形类,四边形继承三角形类、五边形继承四边形类,创建对象统一使用多态创建等等,这样修改的好处是我能够减少一些常用代码的使用频率,需要的时候直接使用对象的getter方法获取对象的固有属性即可。
2.分析类图可得,相比于第一题,这次的类图复杂度有所降低,还体现类与类之间的继承关系,说明更改基础架构确实能够减少不必要的依赖关系。
3.分析代码分析图可得,由于我在处理case4的判断多边形与多边形位置关系的方法和case6判断多边形类型的方法中使用了大量的if语句,导致代码的平均深度和最大深度略高于期望值,同时部分算法设计时不合理,导致圈复杂度不是非常理想,代码冗余度还是偏高。
期中考试
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
源码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
double x1 = sc.nextDouble();
double y1 = sc.nextDouble();
double x2 = sc.nextDouble();
double y2 = sc.nextDouble();
String color= sc.nextLine();
color = sc.nextLine();
if((x1>200||x1<=0)||(y1>200||y1<=0)||(x2>200||x2<=0)||(y2>200||y2<=0))
{
System.out.println("Wrong Format");
return;
}
else
{
Point point1=new Point(x1,y1);
Point point2=new Point(x2,y2);
Line line=new Line(point1,point2,color);
line.display();
}
}
}
class Point {
private double x, y;
public Point() {
}
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public void display() {
System.out.println("("+String.format("%.2f",getX())+","+String.format("%.2f",getY())+")");
}
}
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 void setPoint1(Point point1) {
this.point1 = point1;
}
public Point getPoint2() {
return point2;
}
public void setPoint2(Point point2) {
this.point2 = point2;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void display() {
System.out.println("The line's color is:"+getColor());
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.println("The line's length is:"+String.format("%.2f",getDistance()));
}
public double getDistance()
{
return Math.sqrt(Math.pow(point1.getX()-point2.getX(),2)+Math.pow(point1.getY()-point2.getY(),2));
}
}
类图如下:

SourceMonitor的代码分析图如下:


分析:
1.第一题是后面两题的基础,主要是设计Point类和Line类,根据题目类图提示,往这两个类中增加相应私有属性,并生成对应getter和setter方法即可,此外,还需要分别实现display方法,便于展示数据。
2.分析类图可得,Line类中有Point对象作为属性值,因此存在依赖关系,Main类中创建了Point类和Line类的对象,与两者均有依赖关系,此外两个类的display方法还需要调用获取自身的属性,因此存在自我调用情况。
3.分析代码分析图可得,由于该代码实现的功能较为简单,其圈复杂度和最大深度均在推荐区间以内,可塑性和可复用性均不错。
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
源码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
double x1 = sc.nextDouble();
double y1 = sc.nextDouble();
double x2 = sc.nextDouble();
double y2 = sc.nextDouble();
String color= sc.nextLine();
color = sc.nextLine();
if((x1>200||x1<=0)||(y1>200||y1<=0)||(x2>200||x2<=0)||(y2>200||y2<=0))
{
System.out.println("Wrong Format");
return;
}
else
{
Element point1=new Point(x1,y1);
point1.display();
Element point2=new Point(x2,y2);
point2.display();
Element line=new Line((Point) point1, (Point) point2,color);
line.display();
Element plane=new Plane(color);
plane.display();
}
}
}
class Point extends Element{
private double x, y;
public Point() {
}
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public void display() {
System.out.println("("+String.format("%.2f",getX())+","+String.format("%.2f",getY())+")");
}
}
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 void setPoint1(Point point1) {
this.point1 = point1;
}
public Point getPoint2() {
return point2;
}
public void setPoint2(Point point2) {
this.point2 = point2;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public void display() {
System.out.println("The line's color is:"+getColor());
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.println("The line's length is:"+String.format("%.2f",getDistance()));
}
public double getDistance()
{
return Math.sqrt(Math.pow(point1.getX()-point2.getX(),2)+Math.pow(point1.getY()-point2.getY(),2));
}
}
abstract class Element{
public void display(){};
}
class Plane extends Element{
private String color;
public Plane() {}
public Plane(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public void display() {
System.out.println("The Plane's color is:"+getColor());
}
}
类图如下:

SourceMonitor的代码分析图如下:


分析:
1.该题是在第一题的基础上进行一定程度的改造,首先创建Element类作为抽象类,并使得display作为其唯一的抽象方法,之后再创建新的类Plane,其属性为私有的color。最后使得Point类,Line类,Plane类均继承Element类,并强制实现display方法。完后以上操作后再对main类进行修改将对象的创建方式改为多态创建即可。
2.分析类图可得,Plane类、Point类、Line类均继承Element类并强制实现display方法,新增Plane类与main类的依赖关系,其余依赖关系与第一题无异。
3.分析代码分析图可以看出虽然进行了一定程度的修改,但是由于没有增加较多的if判断以及for循环,该程序的圈复杂度以及最大深度依旧比较乐观,均在最佳区间内,代码的复用性较为理想。
7-3 点线面问题再重构(容器类)
题目:
在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。
在原有类设计的基础上,增加一个GeometryObject容器类,其属性为ArrayList
增加该类的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
源码:
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
GeometryObject geometryObject=new GeometryObject();
int choice = input.nextInt();
while(choice != 0) {
switch(choice) {
case 1:{
double x1 = input.nextDouble();
double y1 = input.nextDouble();
if((x1>200||x1<=0)||(y1>200||y1<=0))
{
System.out.println("Wrong Format");
return;
}
Element point=new Point(x1,y1);
geometryObject.add(point);
break;
}
case 2:{
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
String color= input.nextLine();
color = input.nextLine();
if((x1>200||x1<=0)||(y1>200||y1<=0)||(x2>200||x2<=0)||(y2>200||y2<=0))
{
System.out.println("Wrong Format");
return;
}
Element point1=new Point(x1,y1);
Element point2=new Point(x2,y2);
Element line=new Line((Point) point1, (Point) point2,color);
geometryObject.add(line);
break;
}
case 3:
{
String color= input.nextLine();
color = input.nextLine();
Element plane=new Plane(color);
geometryObject.add(plane);
break;
}
case 4:{
int index = input.nextInt();
geometryObject.remove(index);
}
}
choice = input.nextInt();
}
ArrayList<Element> list = geometryObject.getList();
for (Element element : list) {
element.display();
}
}
}
class Point extends Element{
private double x, y;
public Point() {
}
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public void display() {
System.out.println("("+String.format("%.2f",getX())+","+String.format("%.2f",getY())+")");
}
}
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 void setPoint1(Point point1) {
this.point1 = point1;
}
public Point getPoint2() {
return point2;
}
public void setPoint2(Point point2) {
this.point2 = point2;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public void display() {
System.out.println("The line's color is:"+getColor());
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.println("The line's length is:"+String.format("%.2f",getDistance()));
}
public double getDistance()
{
return Math.sqrt(Math.pow(point1.getX()-point2.getX(),2)+Math.pow(point1.getY()-point2.getY(),2));
}
}
abstract class Element{
public void display(){};
}
class Plane extends Element{
private String color;
public Plane() {}
public Plane(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public void display() {
System.out.println("The Plane's color is:"+getColor());
}
}
class GeometryObject{
ArrayList<Element> elements=new ArrayList<>();
public void add(Element temp)
{
elements.add(temp);
}
public void remove(int index)
{
if(index<=elements.size())
elements.remove(index-1);
}
public ArrayList<Element> getList()
{
return elements;
}
}
类图如下:

SourceMonitor的代码分析图如下:


分析:
1.本题主要考察对象的容器以及其遍历,需要新建一个GeometryObject容器类,其包含的属性为ArrayList<Element>,之后完成类图要求,增加ArrayList的增加元素方法和减少元素方法以及获取List表的方法,同时修改main类,将构造改成与题目提示相同,同时遇上一提类似,使用多态创建对象。
2.分析类图可得,本题在第二题测基础上新增了main与GeometryObject类的依赖,其他与上一题无异。
3.分析代码分析图可得,由于增加了Switch,导致代码判断的情况增加,最大深度略微超过期望值,其他各项均在期望范围内,代码冗余度在总体上而言属于可控范围内。
3.踩坑心得
1.由于第五次作业的case3讨论截线与多边形位置关系的时候错误考虑了截线是否经过多边形的端点的情况,导致穷举了非常多的情况,再加上变量名字取得过于长,导致程序实际上占用内存远大于50kb,pta不让提交代码,后来重新设置算法,不考虑截线是否经过端点,删除绝大部分if,改为遍历截线与多边形两条边的关系来确定截出来的三角形或者四边形的具体点,最后终于通过。

2.第五次作业第二题求多边形相交面积式,在求两个五边形所有交点并去重后,没有用向量法将得到的点进行排序,使其按序能够组成多边形,结果导致求面积的结果错误。后来才专门写了排序算法,根据相邻两个交点与重心组成的边的向量的内积结果来判断点的位置,最终再将结果代入求面积的方法,求得正确面积


4.代码改进建议
1.第四次作业的第二题需要重新构建代码逻辑,增加多边形抽象类,提取公共属性和公共方法作为强制实现方法,同时使三角形、四边形、五边形继承多边形类,裁撤judge类,将方法整合到多边形类中,删除多余的同种功能代码,使用重载实现同种方法的不同实现,同理,也可以这么修改第五次作业的第一题。
2.将过于长的且使用频率相当高的变量名,例如point,triangle等使用其缩写代替,比如p、tr等等,在保证能看懂代码的前提下尽量减少文本所占内存。
3.尽量多用继承与多态实现代码逻辑,并且减少main类中的实现方法,将方法分配给工具类完成,main类只作为程序开始的接口。
5.作业总结
通过完成第四、第五次pta作业以及本次期中考试,我进一步了解了java的继承与多态的性质,构造合理代码结构的能力也得到了锻炼。对我来说,这几次作业不仅仅是任务,更是考验。一次次地修改自己的代码、调试、纠错、提交、再调试、纠错...很难说是一种非常美好的体验。这与其说是与测试点博弈,不如说是与内心不愿意服输的自己博弈,我在这些作业上花费了不少的时间,也经历过好几次测试点无论如何也没办法通过的情况,最终都是选择重头再来,重新构思,最后才顺利通过。这种必须放弃之前成果的行为,对我来说其实相当难以忍受,因为谁也不能保证修改后的代码能够顺利运行,能够丝毫不差,重构意味着放弃现有的既得利益。但有话说得好,当断不断,必受其乱,我很庆幸自己选择破釜沉舟,再干一票,希望之后的自己遇到这种局面,也能这么豁达和从容吧。
给老师的建议:希望四边形与五边形的题目提示中能够增加程序类图,帮助学生快速认识代码逻辑结构。

浙公网安备 33010602011771号