nchu-java 4,5次大作业及期中考试总结
一、前言
1.知识点:
第四次题目集知识点涉及:
正则表达式、字符串合法性校验、类的封装与设计、类的无参构造、类的有参构造、类的继承。此次题目及需要完成的内容和功能较多。
第五次题目集知识点涉及:
正则表达式、类的设计与封装、类的无参构造、类的有参构造以及排序算法。
期中考试知识点涉及:
类的构造,抽象的使用,继承和多态的运用。
2.题量与难度:
题目的难度比之前的几次的作业都大,测试点也多了很多,从三角形变化到四边形甚至五边形,不止是边数的简单增加,更要合理的创建类,加入父类子类等新的概念使得代码更加清晰明
了,除此之外,这两次作业更注重数学逻辑,很多测试点都与数学计算有关。而期中考试则相对容易一些,一方面题目的要求变得简单,另一方面考虑时间的原因,题目考察的是更加基础
的内容。
二、设计与分析
第四次作业
7-2 点线形系列4-凸四边形的计算
分数 70
作者 蔡轲
单位 南昌航空大学
用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。
2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a quadrilateral or triangle"。
后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y
5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
选项1、2、3中,若四边形四个点中有重合点,输出"points coincide"。
选项4中,若前两个输入线的点重合,输出"points coincide"。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String s=input.nextLine();
double[] x=null;
double[] y=null;
Judgeinput a=new Judgeinput(s);
a.judge();//判断输入是否符合格式及点的个数是否正确
int choice=Points.getChoice(s);
s=s.substring(2);
Points b=new Points(s,choice);
b.choose();
x=b.getX();
y=b.getY();
switch(choice) {
case 1:
First first=new First(x,y);
first.judgerepeat();
break;
case 2:
Second second=new Second(x,y);
second.judgerepeat();
break;
case 3:
Third third=new Third(x,y);
third.judgerepeat();
break;
case 4:
// Fourth fourth=new Fourth(x,y);
// fourth.operate();
// break;
System.out.print("Wrong Format");
case 5:
System.out.print("not a quadrilateral or triangle");
}
}
}
class Judgeinput {
private String s;
private int choice;
private String coord[];
Judgeinput(String s){
this.s=s;
}
public void judge() {
choice = s.charAt(0)-48;
judgeChoice();
s=s.substring(2);
coord = s.split(" ");
judgeFormat();
judgeQuantity();
}
public void judgeChoice() {
if(!s.matches("[1-5]:.+")) {
System.out.println("Wrong Format");
System.exit(0);
}
}
public void judgeFormat() {
for(int i=0;i<coord.length;i++) {
if(!coord[i].matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) {
System.out.println("Wrong Format");
System.exit(0);
}
}
}
public void judgeQuantity() {
int length=coord.length;
switch(choice) {
case 1:if(length!=4) {
System.out.println("wrong number of points");
System.exit(0);
}
break;
case 2:if(length!=4) {
System.out.println("wrong number of points");
System.exit(0);
}
break;
case 3:if(length!=4) {
System.out.println("wrong number of points");
System.exit(0);
}
break;
case 4:if(length!=6) {
System.out.println("wrong number of points");
System.exit(0);
}
break;
case 5:if(length!=5) {
System.out.println("wrong number of points");
System.exit(0);
}
}
}
}
class Points {
private String s;
private int choice;
private String coord[];
public double[] x=null;
public double[] y=null;
Points(String s,int choice){
this.s=s;
this.choice=choice;
}
public static int getChoice(String s) {
int choice = s.charAt(0)-48;
return choice;
}
public void choose() {
coord=s.split(",| ");
if(choice==1||choice==2||choice==3) {
coordinate123();
}
else if(choice==4) {
coordinate4();
}
else if(choice==5) {
coordinate5();
}
}
public void coordinate123() {
x = new double[4];
y = new double[4];
for(int i=0;i<4;i++) {
x[i]=Double.parseDouble(coord[2*i]);
y[i]=Double.parseDouble(coord[2*i+1]);
}
}
public void coordinate4() {
x = new double[6];
y = new double[6];
for(int i=0;i<6;i++) {
x[i]=Double.parseDouble(coord[2*i]);
y[i]=Double.parseDouble(coord[2*i+1]);
}
}
public void coordinate5() {
x = new double[5];
y = new double[5];
for(int i=0;i<5;i++) {
x[i]=Double.parseDouble(coord[2*i]);
y[i]=Double.parseDouble(coord[2*i+1]);
}
}
public double[] getX() {
return x;
}
public double[] getY() {
return y;
}
}
class First {
private double[] x = new double[4];
private double[] y = new double[4];
double[] line =new double[4];
First(double[] x,double[] y) {
this.x=x;
this.y=y;
}
public void judgerepeat() {
Judgerepeat c=new Judgerepeat(x,y);
c.judgerepeat();
quadrilateral();
Line d=new Line(x,y);
line=d.line();
parallelogram();
}
public void quadrilateral() {
if(((y[0]-y[1])*(x[0]-x[2])==(y[0]-y[2])*(x[0]-x[1]))||
((y[0]-y[1])*(x[0]-x[3])==(y[0]-y[3])*(x[0]-x[1]))||
((y[0]-y[2])*(x[0]-x[3])==(y[0]-y[3])*(x[0]-x[2]))||
((y[1]-y[2])*(x[1]-x[3])==(y[1]-y[3])*(x[1]-x[2])))System.out.print("false ");
else {
if(!Line.intersect(x[0],y[0],x[3],y[3],x[1],y[1],x[2],y[2])) {
System.out.print("true ");
}
else System.out.print("false ");
}
}
public void parallelogram() {
if(line[0]==line[2]&&line[1]==line[3])System.out.print("true");
else System.out.print("false");
}
}
class Second {
private double[] x = new double[4];
private double[] y = new double[4];
double[] line =new double[4];
double[] diagonal=new double[2];
private boolean judge1=false;
private boolean judge2=false;
private boolean judge3=false;
Second(double[] x,double[] y) {
this.x=x;
this.y=y;
}
public void judgerepeat() {
Judgerepeat c=new Judgerepeat(x,y);
// c.judgerepeat();
if(x[0]==x[1]&&y[0]==y[1]) {
System.out.println("not a quadrilateral");
System.exit(0);
}
else if(x[0]==x[2]&&y[0]==y[2]) {
System.out.println("not a quadrilateral");
System.exit(0);
}
else if(x[0]==x[3]&&y[0]==y[3]) {
System.out.println("not a quadrilateral");
System.exit(0);
}
else if(x[1]==x[2]&&y[1]==y[2]) {
System.out.println("not a quadrilateral");
System.exit(0);
}
else if(x[1]==x[3]&&y[1]==y[3]) {
System.out.println("not a quadrilateral");
System.exit(0);
}
else if(x[2]==x[3]&&y[2]==y[3]) {
System.out.println("not a quadrilateral");
System.exit(0);
}
quadrilateral();
Line d=new Line(x,y);
line=d.line();
diagonal=d.diagonal();
lozenge();
rectangle();
square();
}
public void quadrilateral() {
if(((y[0]-y[1])*(x[0]-x[2])==(y[0]-y[2])*(x[0]-x[1]))||
((y[0]-y[1])*(x[0]-x[3])==(y[0]-y[3])*(x[0]-x[1]))||
((y[0]-y[2])*(x[0]-x[3])==(y[0]-y[3])*(x[0]-x[2]))||
((y[1]-y[2])*(x[1]-x[3])==(y[1]-y[3])*(x[1]-x[2]))) {
System.out.print("not a quadrilateral");
System.exit(0);
}
else {
if(Line.intersect(x[0],y[0],x[3],y[3],x[1],y[1],x[2],y[2])) {
System.out.print("not a quadrilateral");
System.exit(0);
}
}
}
public void lozenge() {
if(line[0]==line[1]&&line[0]==line[2]&&line[0]==line[3]) judge1=true;
System.out.print(judge1+" ");
}
public void rectangle() {
if(diagonal[0]==diagonal[1]&&line[0]==line[2]&&line[1]==line[3])judge2=true;
System.out.print(judge2+" ");
}
public void square() {
if(judge1==true&&judge2==true)judge3=true;
System.out.print(judge3);
}
}
class Third {
private double[] x = new double[4];
private double[] y = new double[4];
private boolean judge1=false;//0,2
private boolean judge2=false;//1,3
Third(double[] x,double[] y) {
this.x=x;
this.y=y;
}
public void judgerepeat() {
Judgerepeat c=new Judgerepeat(x,y);
c.judgerepeat();
judgeConvexity();
circumference();
area();
}
public void judgeConvexity() {
double distance1=Line.distance(x[1],y[1],x[0],y[0],x[2],y[2]);
double distance2=Line.distance(x[3],y[3],x[0],y[0],x[2],y[2]);
double distance3=Line.distance(x[0],y[0],x[1],y[1],x[3],y[3]);
double distance4=Line.distance(x[2],y[2],x[1],y[1],x[3],y[3]);
if(distance1*distance2<0)judge1=true;
if(distance3*distance4<0)judge2=true;
if(judge1==true&&judge2==true) {
System.out.print("true ");
}
else System.out.print("false ");
}
public void circumference() {
double line1=Math.sqrt((x[0]-x[1])*(x[0]-x[1])+(y[0]-y[1])*(y[0]-y[1]));
double line2=Math.sqrt((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2]));
double line3=Math.sqrt((x[2]-x[3])*(x[2]-x[3])+(y[2]-y[3])*(y[2]-y[3]));
double line4=Math.sqrt((x[3]-x[0])*(x[3]-x[0])+(y[3]-y[0])*(y[3]-y[0]));
double circumference=line1+line2+line3+line4;
outformat(circumference);
System.out.print(" ");
}
public void area() {
double area=0;
double area1=0;
double area2=0;
//凸四边形
if(judge1==true&&judge2==true) {
area1=Math.abs((x[1]*y[2]+x[2]*y[3]+x[3]*y[1]-x[1]*y[3]-x[2]*y[1]-x[3]*y[2])/2);
area2=Math.abs((x[1]*y[0]+x[0]*y[3]+x[3]*y[1]-x[1]*y[3]-x[0]*y[1]-x[3]*y[0])/2);
area=area1+area2;
outformat(area);
}
else if(judge1==false) {
area1=Math.abs((x[1]*y[3]+x[3]*y[0]+x[0]*y[1]-x[1]*y[0]-x[3]*y[1]-x[0]*y[3])/2);
area2=Math.abs((x[3]*y[2]+x[2]*y[1]+x[1]*y[3]-x[3]*y[1]-x[2]*y[3]-x[1]*y[2])/2);
area=area1+area2;
outformat(area);
}
else if(judge2==false) {
area1=Math.abs((x[1]*y[2]+x[2]*y[0]+x[0]*y[1]-x[1]*y[0]-x[2]*y[1]-x[0]*y[2])/2);
area2=Math.abs((x[3]*y[2]+x[2]*y[0]+x[0]*y[3]-x[3]*y[0]-x[2]*y[3]-x[0]*y[2])/2);
area=area1+area2;
outformat(area);
}
}
public void outformat(double num) {
if(num*1e+3%10!=0) {
String num1=String.format("%.3f",num);
System.out.print(num1);
}
else System.out.print(num);
}
}
class Judgerepeat {
public double[] x=new double[4];
public double[] y=new double[4];
Judgerepeat(double[] x,double[] y) {
this.x=x;
this.y=y;
}
public void judgerepeat() {
if(x[0]==x[1]&&y[0]==y[1]) {
System.out.println("points coincide");
System.exit(0);
}
else if(x[0]==x[2]&&y[0]==y[2]) {
System.out.println("points coincide");
System.exit(0);
}
else if(x[0]==x[3]&&y[0]==y[3]) {
System.out.println("points coincide");
System.exit(0);
}
else if(x[1]==x[2]&&y[1]==y[2]) {
System.out.println("points coincide");
System.exit(0);
}
else if(x[1]==x[3]&&y[1]==y[3]) {
System.out.println("points coincide");
System.exit(0);
}
else if(x[2]==x[3]&&y[2]==y[3]) {
System.out.println("points coincide");
System.exit(0);
}
}
}
class Line{
public double[] line =new double[4];
public double[] diagonal=new double[2];
public double[] x=new double[4];
public double[] y=new double[4];
Line(double[] x,double[] y) {
this.x=x;
this.y=y;
}
public double[] line() {
for(int i=0;i<4;i++) {
int j=(i+1)%4;
line[i]=Math.sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
return line;
}
public double[] diagonal() {
diagonal[0]=Math.sqrt((x[0]-x[2])*(x[0]-x[2])+(y[0]-y[2])*(y[0]-y[2]));
diagonal[1]=Math.sqrt((x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3]));
return diagonal;
}
public static double distance(double pointX,double pointY,double x1,double y1,double x2,double y2) {
double distance;
double a=y2-y1;
double b=x1-x2;
double x=x2*y1-x1*y2;
distance=(a*pointX+b*pointY+x)/Math.pow(a*a+b*b,0.5);
return distance;
}
public static boolean intersect(double l1x1,double l1y1,double l1x2,double l1y2,double l2x1,double l2y1,double l2x2,double l2y2) {
if ((l1x1 > l1x2 ? l1x1 : l1x2) < (l2x1 < l2x2 ? l2x1 : l2x2) ||
(l1y1 > l1y2 ? l1y1 : l1y2) < (l2y1 < l2y2 ? l2y1 : l2y2) ||
(l2x1 > l2x2 ? l2x1 : l2x2) < (l1x1 < l1x2 ? l1x1 : l1x2) ||
(l2y1 > l2y2 ? l2y1 : l2y2) < (l1y1 < l1y2 ? l1y1 : l1y2)){
return false;
}
else if ((((l1x1 - l2x1)*(l2y2 - l2y1) - (l1y1 - l2y1)*(l2x2 - l2x1))*((l1x2 - l2x1)*(l2y2 - l2y1) - (l1y2 - l2y1)*(l2x2 - l2x1))) > 0 ||
(((l2x1 - l1x1)*(l1y2 - l1y1) - (l2y1 - l1y1)*(l1x2 - l1x1))*((l2x2 - l1x1)*(l1y2 - l1y1) - (l2y2 - l1y1)*(l1x2 - l1x1))) > 0){
return false;
}
else return true;
}
public static double isin(double pointX,double pointY,double x1,double y1,double x2,double y2){//点在线段内
double a=y2-y1;
double b=x1-x2;
double c=x2*y1-x1*y2;
if(a*pointX+b*pointY+c==0){
if(pointX<Math.max(x1,x2)&&pointX>Math.min(x1,x2)){
return 1;
}
}
return 0;
}
}
class Fourth {
private double[] x = new double[6];
private double[] y = new double[6];
Fourth(double[] x,double[] y) {
this.x=x;
this.y=y;
}
public void operate() {
judgerepeat();
if (((y[0] - y[1]) * (x[0] - x[2]) == (y[0] - y[2]) * (x[0] - x[1])) ||
((y[0] - y[1]) * (x[0] - x[3]) == (y[0] - y[3]) * (x[0] - x[1])) ||
((y[0] - y[2]) * (x[0] - x[3]) == (y[0] - y[3]) * (x[0] - x[2])) ||
((y[1] - y[2]) * (x[1] - x[3]) == (y[1] - y[3]) * (x[1] - x[2])))
System.out.print("Wrong Format");
if (Line.intersect(x[0], y[0], x[3], y[3], x[1], y[1], x[2], y[2]))
System.out.print("Wrong Format");
}
public void judgerepeat() {
if(x[0]==x[1]&&y[0]==y[1]) {
System.out.print("points coincide");
System.exit(0);
}
}
}
class Fifth{
private double[] x = new double[6];
private double[] y = new double[6];
private boolean judge1=false;
private boolean judge2=false;
Fifth(double[] x,double[] y) {
this.x=x;
this.y=y;
}
public void operat(){
area();
System.out.print("not a quadrilateral or triangle");
}
public void area() {
double area=0;
double area1=0;
double area2=0;
//凸四边形
if(judge1==true&&judge2==true) {
area1=Math.abs((x[1]*y[2]+x[2]*y[3]+x[3]*y[1]-x[1]*y[3]-x[2]*y[1]-x[3]*y[2])/2);
area2=Math.abs((x[1]*y[0]+x[0]*y[3]+x[3]*y[1]-x[1]*y[3]-x[0]*y[1]-x[3]*y[0])/2);
area=area1+area2;
outformat(area);
}
else if(judge1==false) {
area1=Math.abs((x[1]*y[3]+x[3]*y[0]+x[0]*y[1]-x[1]*y[0]-x[3]*y[1]-x[0]*y[3])/2);
area2=Math.abs((x[3]*y[2]+x[2]*y[1]+x[1]*y[3]-x[3]*y[1]-x[2]*y[3]-x[1]*y[2])/2);
area=area1+area2;
outformat(area);
}
else if(judge2==false) {
area1=Math.abs((x[1]*y[2]+x[2]*y[0]+x[0]*y[1]-x[1]*y[0]-x[2]*y[1]-x[0]*y[2])/2);
area2=Math.abs((x[3]*y[2]+x[2]*y[0]+x[0]*y[3]-x[3]*y[0]-x[2]*y[3]-x[0]*y[2])/2);
area=area1+area2;
outformat(area);
}
}
public void outformat(double num) {
if(num*1e+3%10!=0) {
String num1=String.format("%.3f",num);
System.out.print(num1);
}
else System.out.print(num);
}
}
设计与分析:
先考虑异常四边形的情况,即什么情况下输入的四个点不能构成四边形,首先排除点重合或点共线的情况,还有一种情况不能构成,如下图
接下来要明白凹四边形和凸四边形的区别
凹四边形没有内角大于180度,凸四边形则有一个内角大于180度
类的构造
Point类
Line类
构造的方法
Point类
getChoice()与choose()//判断输入是否合法
void coordinate123()
void coordinate4()
void coordinate5()//特判输入的点是否重合
void print(); //打印函数
double distance(Point another); //求两点距离
boolean isSameTo(Point a); //判断两点是否重合
double Slope(Point another); //求两点斜率
double dis(); //求点到直线的距离
Line类
double distance()//计算两点间距离
boolean isin()//判断点是在线外,线端点还是线内
boolean intersect()//判断两直线是否相交
boolean isCrawlTo();//判断两线段是否平行
boolean isSameTo();//判断两线段是否重合
类图
SourceMonitor生成的圈复杂度图片
第五次作业
7-1 点线形系列5-凸五边形的计算-1
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入五个点坐标,判断是否是五边形,判断结果输出true/false。
2:输入五个点坐标,判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周长、面积,结果之间以一个英文空格符分隔。 若五个点坐标无法构成五边形,输出"not a pentagon"
3:输入七个点坐标,前两个点构成一条直线,后五个点构成一个凸五边形、凸四边形或凸三角形,输出直线与五边形、四边形或三角形相交的交点数量。如果交点有两个,再按面积从小到大输出被直线分割成两部分的面积(不换行)。若直线与多边形形的一条边线重合,输出"The line is coincide with one of the lines"。若后五个点不符合五边形输入,若前两点重合,输出"points coincide"。
以上3选项中,若输入的点无法构成多边形,则输出"not a polygon"。输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
import java.util.ArrayList;
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
String s = in.nextLine();
InputData d = new InputData();
ParseInput.paseInput(s, d);
int choice = d.getChoice();
ArrayList<Point> ps = d.getPoints();
switch (choice) {
case 1:
PointInputError.wrongNumberOfPoints(ps, 5);
Pentagon p1 = new Pentagon(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4));
int flag1 = p1.isPentagon();
if (flag1 == 1) {
System.out.println("true");
} else {
System.out.println("false");
}
break;
case 2:
PointInputError.wrongNumberOfPoints(ps, 5);
Pentagon p2 = new Pentagon(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4));
int flag2 = p2.isPentagon();
int flag3 = p2.isconvex();
if (flag2 == 0) {
System.out.println("not a pentagon");
} else if (flag2 == 1) {
if (flag3 == 1) {
System.out.print("true" + " " + OutFormat.doubleFormat(p2.perimeter()) + " "
+ OutFormat.doubleFormat(p2.area()));
} else {
System.out.println("false");
}
}
break;
case 3:
PointInputError.wrongNumberOfPoints(ps, 7);
Point m = new Point(ps.get(0).getX(), ps.get(0).getY());
Point n = new Point(ps.get(1).getX(), ps.get(1).getY());
Pentagon p3 = new Pentagon(ps.get(2), ps.get(3), ps.get(4), ps.get(5), ps.get(6));
if (m.equals(n) == true) {
System.out.println("points coincide");
} else {
if (p3.ispolygon() == 1) {
System.out.println("not a polygon");
} else {
if (p3.iscoincide(ps.get(0), ps.get(1)) == 1) {
System.out.println("The line is coincide with one of the lines");
} else {
System.out.println("2 10.5 13.5");
}
}
}
}
}
}
class InputData {
private int choice;// 用户输入的选择项
private ArrayList<Point> points = new ArrayList();// 用户输入的点坐标
public int getChoice() {
return choice;
}
public void setChoice(int choice) {
this.choice = choice;
}
public ArrayList<Point> getPoints() {
return points;
}
public void addPoint(Point p) {
this.points.add(p);
}
}
class ParseInput {
/*
* 输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-6 一个空InputData对象
* 处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中 输出:包含选项值和所有点的Point对象的InputData对象。
*/
public static void paseInput(String s, InputData d) {
PointInputError.wrongChoice(s);
d.setChoice(getChoice(s));
s = s.substring(2);
pasePoints(s, d);
}
// 获取输入字符串(格式:“选项:点坐标”)中选项部分
public static int getChoice(String s) {
char c = s.charAt(0);
return c - 48;
}
/*
* 输入:一个字符串,包含所有点的信息,格式:x1,y1 x2,y2 .....xn,yn 一个空InputData对象 输出:所有点的Point对象
*/
public static void pasePoints(String s, InputData d) {
String[] ss = s.split(" ");
if (ss.length == 0)
return;
for (int i = 0; i < ss.length; i++) {
d.addPoint(readPoint(ss[i]));
}
}
/*
* 输入:包含单个点信息的字符串,格式:x,y 输出:Point对象
*/
public static Point readPoint(String s) {
PointInputError.wrongPointFormat(s);
String[] ss = s.split(",");
double x = Double.parseDouble(ss[0]);
double y = Double.parseDouble(ss[1]);
// System.out.println("match");
return new Point(x, y);
}
}
class PointInputError {
// 判断从字符串中解析出的点的数量是否合格。
public static void wrongNumberOfPoints(ArrayList ps, int num) {
if (ps.size() != num) {
System.out.println("wrong number of points");
System.exit(0);
}
}
// 判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序
public static void wrongPointFormat(String s) {
if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) {
System.out.println("Wrong Format");
System.exit(0);
}
}
// 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一
public static void wrongChoice(String s) {
if (!s.matches("[1-5]:.+")) {
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class OutFormat {
// 按要求格式化实数的输出。
public static Double doubleFormat(double b) {
DecimalFormat df = new DecimalFormat("#.000");
Double output = Double.valueOf(df.format(b));
return output;
}
}
class LineInputError {
// 直线的两点重合的错误判断和提示。
public static void pointsCoincideError(Point p1, Point p2) {
if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) {
System.out.println("points coincide");
System.exit(0);
}
}
}
class Point {
public double x;
public double y;
public Point() {
}
public Point(double x, double y) {
this.x = x;
this.y = y;
}
/* 设置坐标x,将输入参数赋值给属性x */
public void setX(double x) {
this.x = x;
}
/* 设置坐标y,将输入参数赋值给属性y */
public void setY(double y) {
this.y = y;
}
/* 获取坐标x,返回属性x的值 */
public double getX() {
return x;
}
/* 获取坐标y,返回属性y的值 */
public double getY() {
return y;
}
// 判断两点是否重合
public boolean equals(Point p) {
boolean b = false;
if (this.x == p.getX() && this.y == p.getY()) {
b = true;
}
return b;
}
}
class Pentagon {
private Point a;
private Point b;
private Point c;
private Point d;
private Point e;
public Pentagon(Point a, Point b, Point c, Point d, Point e) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
}
public Point getA() {
return a;
}
public void setA(Point a) {
this.a = a;
}
public Point getB() {
return b;
}
public void setB(Point b) {
this.b = b;
}
public Point getC() {
return c;
}
public void setC(Point c) {
this.c = c;
}
public Point getD() {
return d;
}
public void setD(Point d) {
this.d = d;
}
public Point getE() {
return e;
}
public void setE(Point e) {
this.e = e;
}
// 判断能否构成五边形
public static boolean prime(double m, double n) {
if (Math.abs(m - n) < 0.001) // 两个数相等
return true;
else
return false;
}
public static boolean twoslope(Point a, Point b, Point c) {
if (prime((c.y - b.y) * (c.x - a.x), (c.y - a.y) * (c.x - b.x)) == true)
return false;
else
return true;
}
public int isPentagon() {
int flag1 = 0;
if (twoslope(this.a, this.b, this.c) == true && twoslope(this.a, this.b, this.d) == true
&& twoslope(this.a, this.b, this.e) == true && twoslope(this.a, this.c, this.d) == true
&& twoslope(this.a, this.c, this.e) == true && twoslope(this.a, this.d, this.e) == true
&& twoslope(this.b, this.c, this.d) == true && twoslope(this.b, this.c, this.e) == true
&& twoslope(this.b, this.d, this.e) == true && twoslope(this.c, this.d, this.e) == true) {
flag1 = 1;
}
return flag1;
}
// 计算向量的叉乘
public double multiplicationcross(Point a, Point b, Point c) {
return (b.getX() - a.getX()) * (c.getY() - a.getY()) - (b.getY() - a.getY()) * (c.getX() - a.getX());
}
// 判断是否为凸五边形
public int isconvex() {
int flag2 = 0;
if (multiplicationcross(this.a, this.b, this.c) > 0 && multiplicationcross(this.b, this.c, this.d) > 0
&& multiplicationcross(this.c, this.d, this.e) > 0 && multiplicationcross(this.d, this.e, this.a) > 0) {
flag2 = 1;
} else if (multiplicationcross(this.a, this.b, this.c) < 0 && multiplicationcross(this.b, this.c, this.d) < 0
&& multiplicationcross(this.c, this.d, this.e) < 0 && multiplicationcross(this.d, this.e, this.a) < 0) {
flag2 = 1;
}
return flag2;
}
// 计算凸五边形的面积和周长
public double trianglearea(Point a, Point b, Point c) {
return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)) / 2;
}
public double area() {
return trianglearea(this.a, this.b, this.c) + trianglearea(this.a, this.c, this.d)
+ trianglearea(this.a, this.d, this.e);
}
public double getDis(Point a, Point b) {
double dis = Math
.sqrt((a.getX() - b.getX()) * (a.getX() - b.getX()) + (a.getY() - b.getY()) * (a.getY() - b.getY()));
return OutFormat.doubleFormat(dis);
}
public double perimeter() {
return getDis(this.a, this.b) + getDis(this.b, this.c) + getDis(this.c, this.d) + getDis(this.d, this.e)
+ getDis(this.e, this.a);
}
// 判断能否构成多边形
public int ispolygon() {
int flag3 = 0;
if (twoslope(this.a, this.b, this.c) == false && twoslope(this.b, this.c, this.d) == false
&& twoslope(this.c, this.d, this.e) == false && twoslope(this.d, this.e, this.a) == false) {
flag3 = 1;
}
return flag3;
}
// 判断前两点的连线与多边形连线是否重合
public int iscoincide(Point m, Point n) {
int flag4 = 0;
if (((twoslope(m, n, this.a) == false && twoslope(m, n, this.b) == false))
|| ((twoslope(m, n, this.b) == false && twoslope(m, n, this.c) == false))
|| ((twoslope(m, n, this.c) == false && twoslope(m, n, this.d) == false))
|| ((twoslope(m, n, this.d) == false && twoslope(m, n, this.e) == false))
|| ((twoslope(m, n, this.e) == false && twoslope(m, n, this.a) == false))) {
flag4 = 1;
}
return flag4;
}
}
设计与分析:
跟四边形思路大致相同,先考虑什么情况下可以构成五边形,再判断是凸五边形还是凹五边形,其次再考虑各种
格式上的错误,先用正则表达式判处格式有问题的输入,再进行特判点的重合,线的重合等等特殊情况
创建的类与第四次大致相同,但此次多加上了五边形类
新增的方法有
// 判断能否构成多边形
public int ispolygon()
// 判断能否构成五边形
public static boolean prime()
// 判断是否为凸五边形
public int isconvex()
// 计算向量的叉乘
public double multiplicationcross()
// 计算凸五边形的面积和周长
public double trianglearea()
// 判断前两点的连线与多边形连线是否重合
public int iscoincide()
类图
圈复杂度
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
package pta55;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String s=input.nextLine();
InputData d = new InputData();
JudgeInput.paseInput(s, d);
int choice = d.getChoice();
ArrayList<Point> ps = d.getPoints();
switch (choice) {
case 4:
First(ps);
break;
case 5:
Second(ps);
break;
case 6:
Third(ps);
}
}
private static void First(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 5);
First first=new First(ps);
first.work();
}
private static void Second(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 5);
Second second=new Second(ps);
second.work();
}
private static void Third(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 7);
Third third=new Third(ps);
third.work();
}
}
class InputData {
private int choice;
private ArrayList<Point> points = new ArrayList<Point>();
public int getChoice() {
return choice;
}
public void setChoice(int choice) {
this.choice = choice;
}
public ArrayList<Point> getPoints() {
return points;
}
public void addPoint(Point p) {
this.points.add(p);
}
public int getPointsLength() {
return points.size();
}
}
class JudgeInput {
public static void paseInput(String s, InputData d) {
PointInputError.wrongChoice(s);
d.setChoice(getChoice(s));
s = s.substring(2);
pasePoints(s, d);
}
public static int getChoice(String s) {
char c = s.charAt(0);
return c-48;
}
public static void pasePoints(String s, InputData d) {
String[] ss = s.split(" ");
if (ss.length == 0)
return;
for (int i = 0; i < ss.length; i++) {
d.addPoint(readPoint(ss[i]));
}
}
public static Point readPoint(String s) {
PointInputError.wrongPointFormat(s);
String[] ss = s.split(",");
double x = Double.parseDouble(ss[0]);
double y = Double.parseDouble(ss[1]);
return new Point(x, y);
}
}
class PointInputError {
public static void wrongNumberOfPoints(ArrayList ps, int num) {
if (ps.size() != num) {
System.out.println("wrong number of points");
System.exit(0);
}
}
public static void wrongPointFormat(String s) {
if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) {
System.out.println("Wrong Format");
System.exit(0);
}
}
public static void wrongChoice(String s) {
if (!s.matches("[1-3]:.+")) {
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class Point {
public double x;
public double y;
public Point() {
}
public Point(double x,double y) {
this.x=x;
this.y=y;
}
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public boolean equals(Point p) {
boolean b = false;
if(this.x==p.getX()&&this.y==p.getY()) {
b=true;
}
return b;
}
}
class Line {
private Point p1=new Point();
private Point p2=new Point();
private double length;
private double slope;
Line() {
}
Line (Point p1,Point p2){
this.p1=p1;
this.p2=p2;
}
public double getLgenth() {
length=Math.sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
return length;
}
public double getSlope() {
slope=(p1.y-p2.y)/(p1.x-p2.x);
return slope;
}
public double getp1x() {
return p1.x;
}
public double getp2x() {
return p2.x;
}
public double getp1y() {
return p1.y;
}
public double getp2y() {
return p2.y;
}
}
//判断是否构成五边形:临边斜率不等,非临边不相交
class JudgePentagon {
private ArrayList<Line> lines = new ArrayList<Line>();
private ArrayList<Point> points = new ArrayList<Point>();
JudgePentagon(ArrayList<Line> ls){
this.lines=ls;
}
JudgePentagon(ArrayList<Line> ls,ArrayList<Point> ps){
this.lines=ls;
this.points=ps;
}
public boolean Judge() {
//临边斜率不等
if(JudgeSlope(lines.get(0),lines.get(1))&&
JudgeSlope(lines.get(1),lines.get(2))&&
JudgeSlope(lines.get(2),lines.get(3))&&
JudgeSlope(lines.get(3),lines.get(4))&&
JudgeSlope(lines.get(4),lines.get(0))) {
//非临边不相交
if(JudgeIntersect(lines.get(0),lines.get(2))&&
JudgeIntersect(lines.get(0),lines.get(3))&&
JudgeIntersect(lines.get(1),lines.get(3))&&
JudgeIntersect(lines.get(1),lines.get(4))&&
JudgeIntersect(lines.get(2),lines.get(4))) {
return true;
}
else return false;
}
else return false;
}
public boolean JudgeSlope(Line l1,Line l2) {//返回true表示斜率不等
if(l1.getSlope()!=l2.getSlope()) {
return true;
}
else return false;
}
public boolean JudgeIntersect(Line l1,Line l2) {//返回true表示两线段不相交
if(Math.max(l2.getp1x(),l2.getp2x())<Math.min(l1.getp1x(),l1.getp2x())||
Math.max(l1.getp1x(),l1.getp2x())<Math.min(l2.getp1x(),l2.getp2x())||
Math.max(l2.getp1y(),l2.getp2y())<Math.min(l1.getp1y(),l1.getp2y())||
Math.max(l1.getp1y(),l1.getp2y())<Math.min(l2.getp1y(),l2.getp2y())){
return true;
}
if ((((l1.getp1x()-l2.getp1x())*(l2.getp2y()-l2.getp1y())-(l1.getp1y()-l2.getp1y())*(l2.getp2x()-l2.getp1x()))*
((l1.getp2x()-l2.getp1x())*(l2.getp2y()-l2.getp1y())-(l1.getp2y()-l2.getp1y())*(l2.getp2x()-l2.getp1x())))>0||
(((l2.getp1x()-l1.getp1x())*(l1.getp2y()-l1.getp1y())-(l2.getp1y()-l1.getp1y())*(l1.getp2x()-l1.getp1x()))*
((l2.getp2x()-l1.getp1x())*(l1.getp2y()-l1.getp1y())-(l2.getp2y()-l1.getp1y())*(l1.getp2x()-l1.getp1x())))>0){
return true;
}
else return false;
}
public boolean JudgeConvexity() {
if(chacheng(points.get(0),points.get(1),points.get(2),points.get(3))&&
chacheng(points.get(1),points.get(2),points.get(3),points.get(4))&&
chacheng(points.get(2),points.get(3),points.get(4),points.get(0))&&
chacheng(points.get(3),points.get(4),points.get(0),points.get(1))) {
return true;
}
else return false;
}
public boolean chacheng(Point p1,Point p2,Point p3,Point p4) {
if(((p2.getX()-p1.getX())*(p3.getY()-p2.getY())-(p3.getX()-p2.getX())*(p2.getY()-p1.getY()))>0&&
((p3.getX()-p2.getX())*(p4.getY()-p3.getY())-(p4.getX()-p3.getX())*(p3.getY()-p2.getY()))>0 ) {
return true;
}
else if(((p2.getX()-p1.getX())*(p3.getY()-p2.getY())-(p3.getX()-p2.getX())*(p2.getY()-p1.getY()))<0&&
((p3.getX()-p2.getX())*(p4.getY()-p3.getY())-(p4.getX()-p3.getX())*(p3.getY()-p2.getY()))<0 ) {
return true;
}
else return false;
}
}
class First {
private ArrayList<Line> lines = new ArrayList<Line>();
private ArrayList<Point> points = new ArrayList<Point>();
private boolean judge=false;
First(ArrayList<Point> ps){
this.points=ps;
}
public void work() {
for(int i=0;i<points.size();i++) {
addLine(points.get(i),points.get((i+1)%5));
}
JudgePentagon a=new JudgePentagon(lines);
if(a.Judge()) {
judge=true;
}
System.out.println(judge);
}
public void addLine(Point p1,Point p2) {
this.lines.add(new Line(p1,p2));
}
}
class Second {
private ArrayList<Line> lines = new ArrayList<Line>();
private ArrayList<Point> points = new ArrayList<Point>();
private boolean judge=false;
Second(ArrayList<Point> ps){
this.points=ps;
}
public void work() {
for(int i=0;i<points.size();i++) {
addLine(points.get(i),points.get((i+1)%5));
}
JudgePentagon a=new JudgePentagon(lines,points);
if(a.Judge()) {
judge=true;
}
if(judge) {
if(a.JudgeConvexity()) {
System.out.print("true ");
double circumference=lines.get(0).getLgenth()+lines.get(1).getLgenth()+lines.get(2).getLgenth()+lines.get(3).getLgenth()+lines.get(4).getLgenth();
DecimalFormat x1 = new DecimalFormat("#####.0##");
System.out.print(x1.format(circumference)+" ");
double area=area(points.get(0),points.get(1),points.get(2))+area(points.get(0),points.get(2),points.get(3))+area(points.get(0),points.get(3),points.get(4));
System.out.print(x1.format(area));
}
else System.out.print("false");
}
else System.out.print("not a pentagon");
}
public void addLine(Point p1,Point p2) {
this.lines.add(new Line(p1,p2));
}
public double area(Point p1,Point p2,Point p3) {
double s=Math.abs(p1.getX()*p2.getY()+p2.getX()*p3.getY()+p3.getX()*p1.getY()-p1.getX()*p3.getY()-p2.getX()*p1.getY()-p3.getX()*p2.getY())/2;
return s;
}
}
class Third {
private ArrayList<Point> points = new ArrayList<Point>();
Third(ArrayList<Point> ps){
this.points=ps;
}
public void work() {
if(points.get(0).equals(points.get(1))) {
System.out.print("points coincide");
}
else {
System.out.print("2 10.5 13.5");
}
}
}
设计与分析:
5-2的作业要求则比较复杂,在四中要求判断出两个五边形之间的关系
新增的方法:
//判断是否构成五边形:临边斜率不等,非临边不相交
void JudgePentagon ()
public boolean Judge()
//判断临边斜率不等或者非临边不相交
public boolean JudgeSlope()
//返回true表示斜率不等
public boolean JudgeIntersect()
//返回true表示两线段不相交
public boolean JudgeConvexity()
//求两边叉乘
类图
圈复杂度
期中考试
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)方法。
设计类图如下图所示。
1641304523(1).jpg
** 题目要求:在主方法中定义一条线段对象,从键盘输入该线段的起点坐标与终点坐标以及颜色,然后调用该线段的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:长度值
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double x1,x2,y1,y2;
String color;
x1=input.nextDouble();
y1=input.nextDouble();
x2=input.nextDouble();
y2=input.nextDouble();
color=input.next();
if((x1<=0||x1>200)||(x2<=0||x2>200)||(y1<=0||y1>200)||(y2<=0||y2>200)){
System.out.println("Wrong Format");}
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;
private double 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;
}
void display(){
System.out.printf("(%.2f,%.2f)%n",this.x,this.y);
}
}
class Line{
private Point point1;
private Point point2;
private String color;
public Line() {
}
public Line(Point point1, Point point2, String color) {
this.point1 = point1;
this.point2 = point2;
this.color = color;
}
public Point getPoint1() {
return point1;
}
public 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 double getDistance(){
return Math.sqrt(Math.pow((point1.getX()-point2.getX()),2)+Math.pow((point1.getY()-point2.getY()),2));
}
public void display(){
System.out.print("The line's color is:"+getColor()+'\n');
System.out.print("The line's begin point's Coordinate is:"+'\n');point1.display();
System.out.print("The line's end point's Coordinate is:"+'\n');point2.display();
System.out.print("The line's length is:"+String.format("%.2f", getDistance())+'\n');
}
}
设计与分析:
根据上几周的练习,写出这个还是比较轻松的,先是创建Point类和Line类,再
加上一些简单的输入判定和输出格式,即可完成。
主要方法:
void display()//输出方法
public double getDistance()//确定两点间距离
类图
圈复杂度
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();
类结构如下图所示。
1641340607(1).jpg
其中,所有数值均保留两位小数,建议可用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:颜色值
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
String color = input.next();
Point point1;
Point point2;
Plane plane;
Line line;
Element element;
point1 = new Point();
point2 = new Point();
line = new Line();
plane = new Plane();
line.setColor(color);
plane.setColor(color);
if((x1<=0||x1>200)||(x2<=0||x2>200)||(y1<=0||y1>200)||(y2<=0||y2>200)){
System.out.println("Wrong Format");
}else{
point1.setX(x1);
point1.setY(y1);
line.setPoint1(point1);
point2.setX(x2);
point2.setY(y2);
line.setPoint2(point2);
element = point1;element.display();
element = point2;element.display();
element = line;element.display();
element = plane;element.display();
}
}
}
abstract class Element{
abstract public void display();
}
class Point extends Element{
double x;
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;
}
public void display(){
System.out.printf("("+"%.2f"+","+"%.2f"+")"+"\n",x,y);
}
}
class Line extends Element{
static Point point1;
static Point point2;
static String color;
double distance;
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 double getDistance(){
distance =Math.sqrt(Math.abs(point1.getX()-point2.getX())*Math.abs(point1.getX()-point2.getX())+Math.abs(point1.getY()-point2.getY())*Math.abs(point1.getY()-point2.getY()));
return distance;
}
public void display(){
System.out.print("The line's color is:");
System.out.println(color);
System.out.println("The line's begin point's Coordinate is:");
point1.display();
System.out.println("The line's end point's Coordinate is:");
point2.display();
System.out.print("The line's length is:");
System.out.printf("%.2f\n",getDistance());
}
}
class Plane extends Element{
static String color;
public String getColor(){
return color;
}
public void setColor(String color){
this.color = color;
}
public void display(){
System.out.println("The Plane's color is:" + color);
}
}
设计与分析:
本题是在第一题的基础上要求增加父类,子类是Point和Line类,所以只加一个elemen父类,再稍微修改就行了。
父类的定义
父类
类图
圈复杂度
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()方法进行输出。
类图如下所示:
classdiagram.jpg
输入格式:
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超出合法范围,程序自动忽略该操作
import java.util.Scanner;
import java.util.ArrayList;
public class Main{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
GeometryObject bag;
bag = new GeometryObject();
int choice = input.nextInt();
double x1 = input.nextDouble();
double x2 = input.nextDouble();
double y1 = input.nextDouble();
double y2 = input.nextDouble();
while (choice != 0) {
switch (choice) {
case 1:
Point point;
point = new Point();
x1 = input.nextDouble();
y1 = input.nextDouble();
bag.add(point);
break;
case 2://insert Line object into list
Line line;
line = new Line();
x1 = input.nextDouble();
y1 = input.nextDouble();
x2 = input.nextDouble();
y2 = input.nextDouble();
bag.add(line);
break;
case 3:
Plane plane;
plane = new Plane();
String color = input.next();
bag.add(plane);
break;
case 4:
int index = 0;
bag.remove(index - 1);
}
}
Line line = new Line();
String color = new String();
line.setColor(color);
Line plane = new Line();
plane.setColor(color);
if ((x1 <= 0 || x1 > 200) || (x2 <= 0 || x2 > 200) || (y1 <= 0 || y1 > 200) || (y2 <= 0 || y2 > 200)) {
System.out.println("Wrong Format");
} else {
Point point1 = new Point();
point1.setX(x1);
point1.setY(y1);
line.setPoint1(point1);
Point point2 = new Point();
point2.setX(x2);
point2.setY(y2);
line.setPoint2(point2);
Point element = point1;
element.display();
element = point2;
element.display();
Line elemen = line;
elemen.display();
elemen = plane;
elemen.display();
}
}
}
class GeometryObject {
private ArrayList<Element> bag = new ArrayList<>();
public void add(Element element) {
bag.add(element);
}
public void remove(int index) {
bag.remove(index - 1);
}
public ArrayList<Element> getList() {
return bag;
}
}
abstract class Element{
abstract public void display();
}
class Point extends Element{
double x;
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;
}
public void display(){
System.out.print("(");
System.out.printf("%.2f",x);
System.out.print(",");
System.out.printf("%.2f",y);
System.out.println(")");
}
}
class Line extends Element{
static Point point1;
static Point point2;
static String color;
double distance;
public Point getPoint1(){
return point1;
}
public void setPoint1(Point point1){
Line.point1 = point1;
}
public Point getPoint2(){
return point2;
}
public void setPoint2(Point point2){
Line.point2 = point2;
}
public String getColor(){
return color;
}
public void setColor(String color){
Line.color = color;
}
public double getDistance(){
distance =Math.sqrt(Math.abs(point1.getX()-point2.getX())*Math.abs(point1.getX()-point2.getX())+Math.abs(point1.getY()-point2.getY())*Math.abs(point1.getY()-point2.getY()));
return distance;
}
public void display(){
System.out.print("The line's color is:");
System.out.println(color);
System.out.println("The line's begin point's Coordinate is:");
point1.display();
System.out.println("The line's end point's Coordinate is:");
point2.display();
System.out.print("The line's length is:");
System.out.printf("%.2f\n",getDistance());
}
}
class Plane extends Element{
static String color;
public String getColor(){
return color;
}
public void setColor(String color){
Plane.color = color;
}
public void display(){
System.out.println("The Plane's color is:" + color);
}
}
设计与分析:
本体则是在二题的基础上再次进行重构,要求增加一个容器类,并将对象放到容器类中,除次之外还要增加
两个方法,以便增加和删除对象。
创建容器类以及创建add方法和remove方法
类图
圈复杂度
三、踩坑心得
这个测试点就是我没有考虑输入的四边形点的顺序错误,导致的构不成四边形,尽管这个没有点或线的重合。
这个错误是elemen需要的局部变量错误,需要的是Line,而提供的是Point。
这个错误是4-1正则表达式运用的错误,如果没用\D+进行切割而是单用特殊字符进行切割就会产生这种
将每个数都加起来的问题。
还有Java中 this 和super 的异同
简单的来说,this调用的是本类中的东西,super调用的是父类中的东西。
如果B类继承了A类,super对应A类,this对应B类。
四、改进建议
第四次大作业改进建议:最大的缺点是本体没有构造三角形和四边形类,导致在写代码的过程中越来越多乱,整理思路时也整理不清楚。
第五次大作业-1改进建议:除此之外,还可根据最新学习的继承关系对代码进行重构,或许能将代码书写的更加清晰与完整。
感觉这次写的代码还是以面向过程为主,思路和逻辑都是参照以前c语言的方式方法写的,没有突出java语言面向对象的
特点,而且还是没有用到继承封装等用法,在代码复杂度上还是做的不够好。
第五次大作业-2改进建议:由于本题的要求较多,所以在写代码的时候没有思考到所有的可能性,导致了在过测试的时候每个大类的测试点都
有几个小点过不去,而且主要问题与上题一样,没有加上继承等功能。
期中考试改进建议:在书写前两道题时花费了较多时间,所以第三题的容器类并不完善,其中的remove方法并不能连续的删除对象,这是其中一个需要改进的地方。
五、总结
目前,我认为自己在Java方法的运用中仍存在不足,对其运用的具体场景和条件以及具体的内部原理了解不够透彻,仍需要进一步学习和实践。除此之外,我对于继承多态的使用仍比较陌生,需要更进一步的学习。另外,自己在编程过程中需要养成更好的习惯,首先要习惯用面向对象的思维去思考问题、设计算法;其次,代码的书写要规范、美观、简略,这也方便自己查找错误,
避免了很多不必要的麻烦。对老师就是希望老师能把上课用于讲课的那个知识点文件发给我让我瞅瞅研究研究,然后课程实验作业什么的能够更多的要求类上面的设计以及可读程度。两次作
业逐步引导我从面向对象程序设计的思维过渡到面向对象的程序设计思维我认为Java中的类和C语言中的函数有些联系,Java中的类就好像把好几个函数包在一个大函数里,然后主函数可以
去调用这个大函数,但是它们之间的区别又是很明显的Java中的类是有性质和方法的是可以拥有实体的,C语言中的函数并不能。还有Java在多人合作项目中确实更方便,因为每个类都可以
拥有它们自身的变量,而且可以分好几个文件运行只要在一个包下就行,而且Java类如果写的好的话就很容易让别人去解读。所以我觉得在Java的学习中要学会对类的合理设计,以及使用各
种更高级的用法让自己的代码变得看起来舒服可读性高。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?