题目集4~6、超星作业、期中考试的总结
- (一)前言:题目集04-06考察的主要是点线系列的判断几个点构成的图形及求面积和直线与图形的交点、正则表达式的使用(判断数据及格式是否符合要求)、类的构建设计;一个题目集的的题量在3-5题的范围,答题时间在7天左右;对于我而言难度较大,思考时不能很好地对问题进行细致的分析,但是对于我们有较好的磨练效果。
- (二)题目
1.题目集04 7-3
用户输入一组选项和数据,进行与三角形有关的计算。选项包括:
1:输入三个点坐标,判断是否是等腰三角形、等边三角形,判断结果输出true/false,两个结果之间以一个英文空格符分隔。
2:输入三个点坐标,输出周长、面积、重心坐标,三个参数之间以一个英文空格分隔,坐标之间以英文","分隔。
3:输入三个点坐标,输出是钝角、直角还是锐角三角形,依次输出三个判断结果(true/false),以一个英文空格分隔,
4:输入五个点坐标,输出前两个点所在的直线与三个点所构成的三角形相交的交点数量,如果交点有两个,则按面积大小依次输出三角形被直线分割成两部分的面积。若直线与三角形一条线重合,输出"The point is on the edge of the triangle"
5:输入四个点坐标,输出第一个是否在后三个点所构成的三角形的内部(输出in the triangle/outof triangle)。
必须使用射线法,原理:由第一个点往任一方向做一射线,射线与三角形的边的交点(不含点本身)数量如果为1,则在三角形内部。如果交点有两个或0个,则在三角形之外。若点在三角形的某条边上,输出"on the triangle"
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
如果输入的三个点无法构成三角形,输出"data error"。
注意:输出的数据若小数点后超过6位,只保留小数点后6位,多余部分采用四舍五入规则进到最低位。小数点后若不足6位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333333,1.0按格式输出为1.0
选项4中所输入线的两个点坐标重合,输出"points coincide",
类图:

import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String str = in.nextLine(); if(isDouble(str.substring(0, 1))&&str.length()>1) { switchChoice((int)Double.parseDouble(str.substring(0, 1)),str); } else outPut("Wrong Format"); } public static void switchChoice(int choice,String str) { switch(choice) { case 1:choice(str,1); break; case 2:choice(str,2); break; case 3:choice(str,3); break; case 4:choice1(str); break; case 5:choice2(str); break; default : outPut("Wrong Format"); break; } } public static void choice2(String str1) { double [] num = new double[8]; boolean more=false; if(str1.charAt(1)==':') { int i=2,t=0,m=1; if(i==str1.length()) outPut("Wrong Format"); else if(str1.charAt(i)==48&&str1.charAt(i+1)!='.'&&str1.charAt(i+1)!=',') outPut("Wrong Format"); else if(i<str1.length()) { for(int j=0;j<7;j++) { if(m%2!=0&&i<str1.length()) { t=circle(i,str1,','); } else if(m%2==0&&i<str1.length()){ t=circle(i,str1,' '); } else outPut("Wrong Format"); if(isDouble(str1.substring(i, t))) { num[j]=Double.parseDouble(str1.substring(i, t)); i=t+1; } else outPut("Wrong Format"); if(t==str1.length()) outPut("wrong number of points"); m++; } while((t+1)<str1.length()) { if(str1.charAt(t+1)==',') { more=true; break; } t++; } t=i-1; if(i<str1.length()&&!more) { t=circle(i,str1,'\0'); if(isDouble(str1.substring(i, t))==true) { num[7]=Double.parseDouble(str1.substring(i, t)); if(t==str1.length()) {//操作 double l1,l2,l3; l1=Math.sqrt(Math.pow(num[4]-num[2],2 )+Math.pow(num[5]-num[3], 2)); l2=Math.sqrt(Math.pow(num[6]-num[2],2 )+Math.pow(num[7]-num[3], 2)); l3=Math.sqrt(Math.pow(num[6]-num[4],2 )+Math.pow(num[7]-num[5], 2)); if(l1+l2-l3<0.01||l2+l3-l1<0.01||l1+l3-l2<0.01) outPut("data error"); else { int count =0; double k1=1,k2,k3,k4; double [] num1 = new double[6]; k2=(num[3]-num[5])/(num[2]-num[4]); k3=(num[3]-num[7])/(num[2]-num[6]); k4=(num[5]-num[7])/(num[4]-num[6]); if(num[2]==num[4]) { num1[0]=num[2];//k2 num1[1]=num[2]-num[0]+num[1]; num1[2]=(num[3]-k3*num[2]-num[1]+k1*num[0])/(k1-k3);//k3 num1[3]=(k1*(num[3]-k3*num[2])+k3*(-num[1]+k1*num[0]))/(k1-k3); num1[4]=(num[5]+k1*num[0]-num[1]-k4*num[4])/(k1-k4);//k4 num1[5]=(k1*(num[5]-k4*num[4])+k4*(-num[1]+k1*num[0]))/(k1-k4); if(num[0]==num[2]&&num[1]<=getMax(num[3],num[5])&&num[1]>=getMin(num[3],num[5]) ||(num[1]-k3*(num[0]-num[2])-num[3])==0||(num[1]-k4*(num[0]-num[4])-num[5])==0) { outPut("on the triangle"); } else { for(int j=0;j<5;j=j+2) { if(num1[j]>num[0]&&num1[j]>num[0]&&num1[j]==num[2]&&(num1[j+1]<=getMax(num[3],num[5])&&num1[j+1]<=getMin(num[3],num[5]))) { count=1; break; } } for(int j=0;j<5&&count!=2;j=j+2) { if(num1[j]>num[0]&&num[j+1]>num[1]&&(num1[j]-num[2])*(num1[j]-num[4])<0||(num1[j]-num[2])*(num1[j]-num[6])<0||(num1[j]-num[4])*(num1[j]-num[6])<0) { count++; } } if(count==1) outPut("in the triangle"); else outPut("outof the triangle"); } } else if(num[2]==num[6]) { num1[0]=((num[3]-k2*num[2]-num[1]+k1*num[0]))/(k1-k2);//k2 num1[1]=(k1*(num[3]-k2*num[2])+k2*(-num[1]+k1*num[0]))/(k1-k2); num1[2]=num[2];//k3 num1[3]=k1*(num[2]-num[0])+num[1]; num1[4]=(num[5]+k1*num[0]-num[1]-k4*num[4])/(k1-k4);//k4 num1[5]=(k1*(num[5]-k4*num[4])+k4*(-num[1]+k1*num[0]))/(k1-k4); if(num[0]==num[2]&&num[1]<=getMax(num[3],num[7])&&num[1]>=getMin(num[3],num[7]) ||(num[1]-k2*(num[0]-num[2])-num[3])==0||(num[1]-k4*(num[0]-num[4])-num[5])==0) { outPut("on the triangle"); } else { for(int j=0;j<5;j=j+2) { if(num1[j]>num[0]&&num1[j]==num[2]&&(num1[j+1]<=getMax(num[3],num[7])&&num1[j+1]<=getMin(num[3],num[7]))) { count=1; break; } } for(int j=0;j<5&&count!=2;j=j+2) { if(num1[j]>num[0]&&num[j+1]>num[1]&&(num1[j]-num[2])*(num1[j]-num[4])<0||(num1[j]-num[2])*(num1[j]-num[6])<0||(num1[j]-num[4])*(num1[j]-num[6])<0) { count++; } } if(count==1) outPut("in the triangle"); else outPut("outof the triangle"); } } else if(num[4]==num[6]) { num1[0]=((num[3]-k2*num[2]-num[1]+k1*num[0]))/(k1-k2);//k2 num1[1]=(k1*(num[3]-k2*num[2])+k2*(-num[1]+k1*num[0]))/(k1-k2); num1[2]=(num[3]-k3*num[2]-num[1]+k1*num[0])/(k1-k3);//k3 num1[3]=(k1*(num[3]-k3*num[2])+k3*(-num[1]+k1*num[0]))/(k1-k3); num1[4]=num[4];//k4 num1[5]=k1*(num[4]-num[0])+num[1]; if(num[0]==num[4]&&num[1]<=getMax(num[5],num[7])&&num[1]>=getMin(num[5],num[7]) ||(num[1]-k2*(num[0]-num[2])-num[3])==0||(num[1]-k3*(num[0]-num[2])-num[3])==0) { outPut("on the triangle"); } else { for(int j=0;j<5;j=j+2) { if(num1[j]>num[0]&&num1[j]==num[4]&&(num1[j+1]<=getMax(num[7],num[5])&&num1[j+1]<=getMin(num[7],num[5]))) { count=1; break; } } for(int j=0;j<5&&count!=2;j=j+2) { if(num1[j]>num[0]&&num[j+1]>num[1]&&(num1[j]-num[2])*(num1[j]-num[4])<0||(num1[j]-num[2])*(num1[j]-num[6])<0||(num1[j]-num[4])*(num1[j]-num[6])<0) { count++; } } if(count==1) outPut("in the triangle"); else outPut("outof the triangle"); } } else { num1[0]=((num[3]-k2*num[2]-num[1]+k1*num[0]))/(k1-k2);//k2 num1[1]=(k1*(num[3]-k2*num[2])+k2*(-num[1]+k1*num[0]))/(k1-k2); num1[2]=(num[3]-k3*num[2]-num[1]+k1*num[0])/(k1-k3);//k3 num1[3]=(k1*(num[3]-k3*num[2])+k3*(-num[1]+k1*num[0]))/(k1-k3); num1[4]=(num[5]+k1*num[0]-num[1]-k4*num[4])/(k1-k4);//k4 num1[5]=(k1*(num[5]-k4*num[4])+k4*(-num[1]+k1*num[0]))/(k1-k4); if((num[1]-k2*(num[0]-num[2])-num[3])==0||(num[1]-k4*(num[0]-num[4])-num[5])==0||(num[1]-k3*(num[0]-num[2])-num[3])==0) { outPut("on the triangle"); } else { for(int j=0;j<5&&count!=2;j=j+2) { if((num1[j]>num[0]&&num1[j+1]>num[1])&&((num1[j]-num[2])*(num1[j]-num[4])<0||(num1[j]-num[2])*(num1[j]-num[6])<0||(num1[j]-num[4])*(num1[j]-num[6])<0)) { count++; } } if(count==1) outPut("in the triangle"); else outPut("outof the triangle"); } } } } } else outPut("Wrong Format"); } else if(i<str1.length()&&more) { int j=1; while(i<str1.length()) { if(j%2!=0) { if(i<str1.length()) { t=circle(i,str1,' '); num[7]=Double.parseDouble(str1.substring(i, t)); i=t+1; if(i==str1.length()) { outPut("Wrong Format"); } } else outPut("Wrong Format"); } else { if(i<str1.length()) { t=circle(i,str1,','); num[7]=Double.parseDouble(str1.substring(i, t)); i=t+1; if(i==str1.length()) { outPut("Wrong Format"); } } else outPut("Wrong Format"); } j++; } outPut("wrong number of points");//数量不符合 } else outPut("Wrong Format"); } } else outPut("Wrong Format"); } private static void choice1(String str1) { double [] num = new double[10]; boolean more=false,eq=false; if(str1.charAt(1)==':') { int i=2,t=0,m=1; if(i==str1.length()) outPut("Wrong Format"); else if(str1.charAt(i)==48&&str1.charAt(i+1)!='.'&&str1.charAt(i+1)!=',') outPut("Wrong Format"); else if(i<str1.length()) { for(int j=0;j<9;j++) { if(m%2!=0&&i<str1.length()) { t=circle(i,str1,','); } else if(m%2==0&&i<str1.length()){ t=circle(i,str1,' '); } else outPut("Wrong Format"); if(isDouble(str1.substring(i, t))) { num[j]=Double.parseDouble(str1.substring(i, t)); i=t+1; } else outPut("Wrong Format"); if(t==str1.length()) outPut("wrong number of points"); m++; } while((t+1)<str1.length()) { if(str1.charAt(t+1)==',') { more=true; break; } t++; } t=i-1; if(i<str1.length()&&!more) { t=circle(i,str1,'\0'); if(isDouble(str1.substring(i, t))==true) { num[9]=Double.parseDouble(str1.substring(i, t)); if(t==str1.length()) {//操作 double l1,l2,l3,circu,k2,k3,k4,area1,area2=0,area3; DecimalFormat df = new DecimalFormat("0.0#####"); l1=Math.sqrt(Math.pow(num[6]-num[4],2 )+Math.pow(num[7]-num[5], 2)); l2=Math.sqrt(Math.pow(num[8]-num[4],2 )+Math.pow(num[9]-num[5], 2)); l3=Math.sqrt(Math.pow(num[8]-num[6],2 )+Math.pow(num[9]-num[7], 2)); circu=l1+l2+l3; if(num[0]==num[2]&&num[1]!=num[3]) {//垂直x轴 if(l1+l2-l3<0.01||l2+l3-l1<0.01||l1+l3-l2<0.01) outPut("data error"); else { if(num[4]==num[6]&&num[6]==num[0]||num[4]==num[8]&&num[4]==num[0]||num[6]==num[8]&&num[6]==num[0]) outPut("The point is on the edge of the triangle"); else { area1=getArea(circu,l1,l2,l3); double [] num1=new double[4]; k2=(num[7]-num[5])/(num[6]-num[4]); k3=(num[5]-num[9])/(num[4]-num[8]); k4=(num[7]-num[9])/(num[6]-num[8]); if(num[0]<getMax(getMax(num[4],num[6]),getMax(num[6],num[8]))&&num[0]>getMin(getMin(num[4],num[6]),getMin(num[6],num[8]))){//2 if(num[0]<=getMax(num[4],num[6])&&num[0]>=getMin(num[4],num[6])&&num[0]<=getMax(num[4],num[8])&&num[0]>=getMin(num[4],num[8])) {//4 num1[0]=num[0]; num1[1]=k2*(num[0]-num[4])+num[5]; num1[2]=num[0]; num1[3]=k3*(num[0]-num[4])+num[5]; area2=Math.abs((num1[3]-num1[1])*(num[4]-num[0]))*0.5; } else if(num[0]<=getMax(num[4],num[6])&&num[0]>=getMin(num[4],num[6])&&num[0]<=getMax(num[8],num[6])&&num[0]>=getMin(num[8],num[6])) {//6 num1[0]=num[0]; num1[1]=k2*(num[0]-num[6])+num[7]; num1[2]=num[0]; num1[3]=k4*(num[0]-num[6])+num[7]; area2=Math.abs((num1[3]-num1[1])*(num[6]-num[0]))*0.5; } else if(num[0]<=getMax(num[8],num[6])&&num[0]>=getMin(num[8],num[6])&&num[0]<=getMax(num[4],num[8])&&num[0]>=getMin(num[4],num[8])) { num1[0]=num[0]; num1[1]=k3*(num[0]-num[8])+num[9]; num1[2]=num[0]; num1[3]=k4*(num[0]-num[8])+num[9]; area2=Math.abs((num1[3]-num1[1])*(num[8]-num[0]))*0.5; } area3=area1-area2; if(area2>=area3&&area2!=0) outPut("2 "+df.format(area3)+" "+df.format(area2)); else outPut("2 "+df.format(area2)+" "+df.format(area3)); } else if(num[0]==getMax(getMax(num[4],num[6]),getMax(num[6],num[8]))||num[0]==getMin(getMin(num[4],num[6]),getMin(num[6],num[8]))) { outPut("1"); } else if(num[0]>getMax(getMax(num[4],num[6]),getMax(num[6],num[8]))&&num[0]<getMin(getMin(num[4],num[6]),getMin(num[6],num[8]))) { outPut("0"); } } } } else if(num[0]==num[2]&&num[1]==num[3]) outPut("points coincide"); else {//3 if(l1+l2-l3<0.01||l2+l3-l1<0.01||l1+l3-l2<0.01) outPut("data error"); else { double k1; k1=(num[1]-num[3])/(num[0]-num[2]); k2=(num[7]-num[5])/(num[6]-num[4]); k3=(num[5]-num[9])/(num[4]-num[8]); k4=(num[7]-num[9])/(num[6]-num[8]); if((k1==k2&&k1==(num[1]-num[5])/(num[0]-num[4]))||(k1==k3&&k1==(num[1]-num[5])/(num[0]-num[4]))||(k1==k4&&k1==(num[1]-num[7])/(num[0]-num[6]))) outPut("The point is on the edge of the triangle"); else { double [] max =new double [3]; double [] min=new double [3]; double [] maxy =new double [3]; double [] miny=new double [3]; int count=0,count1=0,count2=0,count3=0,n=-1; double [] num1=new double[6]; if(num[4]==num[6]) {//a num1[0]=num[4];//k2 num1[1]=k1*(num[4]-num[0])+num[1]; num1[2]=(num[1]-k1*num[0]-num[5]+k3*num[4])/(k3-k1);//k3 num1[3]=(k3*(num[1]-k1*num[0])+k1*(-num[5]+k3*num[4]))/(k3-k1); num1[4]=(num[1]-k1*num[0]-num[7]+k4*num[6])/(k4-k1);//k4 num1[5]=(k4*(num[1]-k1*num[0])+k1*(-num[7]+k4*num[6]))/(k4-k1); for(int j=0;j<3;j++) { max[j]=getMax(num[4+j],num[6+j]); min[j]=getMin(num[4+j],num[6+j]); maxy[j]=getMax(num[5+j],num[7+j]); miny[j]=getMin(num[5+j],num[7+j]); } for(int j=0;j<5;j=j+2) { if((num1[j]-num[4]==0&&num1[j+1]<=maxy[0]&&num1[j+1]>=miny[0])||(num1[j]-num[6]==0&&num1[j+1]<=maxy[1]&&num1[j+1]>=miny[1])||(num1[j]-num[8]==0&&num1[j+1]<=maxy[2]&&num1[j+1]>=miny[2])){ count=1; count1=count2=count3=1; break; } }//, for(int j=0;j<5;j=j+2) { if((((num1[j+1]-num[5])*(num1[j+1]-num[7])<0||(num1[j]-num[4])*(num1[j]-num[8])<0)&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<0)&&count1!=2){//4 count1++; } if(((num1[j]-num[4])*(num1[j]-num[8])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<0||(num1[j]-num[8])*(num1[j]-num[6])<0&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<=0)&&count2!=2) {//8 count2++; } if((((num1[j+1]-num[5])*(num1[j+1]-num[7])<0||(num1[j]-num[8])*(num1[j]-num[6])<0)&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<0)&&count3!=2) {//6 count3++; } } count=findMax(count1,count2,count3); if(count<2) outPut(String.valueOf(count)); else { area1=getArea(circu,l1,l2,l3); if(count1==2&&((num1[4]-num[8])*(num1[4]-num[6])>0||(num1[4]==num[8]&&num1[4]==num[6])||(num1[4]==num[4]&&num1[4]==num[6])||(num1[4]==num[4]&&num1[4]==num[8]))) {//4 area2=0.5*Math.abs((num1[3]-num[5])*(num1[0]-num[4])-(num1[2]-num[4])*(num1[1]-num[5])); } else if(count2==2&&((num1[0]-num[4])*(num1[0]-num[8])>0||(num1[0]==num[4]&&num1[0]==num[8])||(num1[0]==num[6]&&num1[0]==num[8])||(num1[0]==num[4]&&num1[0]==num[6]))) {//8 area2=Math.abs((num1[2]-num[8])*(num1[5]-num[9])-(num1[4]-num[8])*(num1[3]-num[9]))*0.5; } else if(count3==2&&((num1[2]-num[6])*(num1[2]-num[4])>0||(num1[2]==num[6]&&num1[2]==num[4])||(num1[2]==num[6]&&num1[2]==num[8])||(num1[2]==num[4]&&num1[2]==num[8]))) {//6 area2=Math.abs((num1[0]-num[6])*(num1[5]-num[7])-(num1[4]-num[6])*(num1[1]-num[7]))*0.5; } area3=Math.abs(area1-area2); area2=area1-area3; if(area2>=area3&&area2!=0) outPut("2 "+df.format(area3)+" "+df.format(area2)); else outPut("2 "+df.format(area2)+" "+df.format(area3)); } }//a else if(num[4]==num[8]){//b num1[0]=(num[5]-k2*num[4]-num[1]+k1*num[0])/(k1-k2);//k2 num1[1]=(k1*(num[5]-k2*num[4])+k2*(-num[1]+k1*num[0]))/(k1-k2); num1[2]=num[4];//k3 num1[3]=k1*(num[4]-num[0])+num[1]; num1[4]=(num[1]-k1*num[0]-num[7]+k4*num[6])/(k4-k1);//k4 num1[5]=(k4*(num[1]-k1*num[0])+k1*(-num[7]+k4*num[6]))/(k4-k1); for(int j=0;j<3;j++) { max[j]=getMax(num[4+j],num[6+j]); min[j]=getMin(num[4+j],num[6+j]); maxy[j]=getMax(num[5+j],num[7+j]); miny[j]=getMin(num[5+j],num[7+j]); } for(int j=0;j<5;j=j+2) { if((num1[j]-num[4]==0&&num1[j+1]<=getMax(num[5],num[9])&&num1[j+1]>=getMin(num[5],num[9]))||(num1[j]-num[6]==0&&num1[j+1]<=maxy[1]&&num1[j+1]>=miny[1])||(num1[j]-num[8]==0&&num1[j+1]<=maxy[2]&&num1[j+1]>=miny[2])){ count=1; count1=count2=count3=1; break; } }//, for(int j=0;j<5;j=j+2) { if(((num1[j]-num[4])*(num1[j]-num[6])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[7])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<0)&&count1!=2){//4 count1++; } if((((num1[j+1]-num[5])*(num1[j+1]-num[9])<0||(num1[j]-num[8])*(num1[j]-num[6])<0)&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<0)&&count2!=2) {//8 count2++; } if(((num1[j]-num[4])*(num1[j]-num[6])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[7])<0||(num1[j]-num[8])*(num1[j]-num[6])<0&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<=0)&&count3!=2) {//6 count3++; } } count=findMax(count1,count2,count3); if(count<2) outPut(String.valueOf(count)); else { area1=getArea(circu,l1,l2,l3); if(count1==2&&((num1[4]-num[8])*(num1[4]-num[6])>0||(num1[4]==num[8]&&num1[4]==num[6])||(num1[4]==num[4]&&num1[4]==num[6])||(num1[4]==num[4]&&num1[4]==num[8]))) {//4 area2=0.5*Math.abs((num1[3]-num[5])*(num1[0]-num[4])-(num1[2]-num[4])*(num1[1]-num[5])); } else if(count2==2&&((num1[0]-num[4])*(num1[0]-num[8])>0||(num1[0]==num[4]&&num1[0]==num[8])||(num1[0]==num[6]&&num1[0]==num[8])||(num1[0]==num[4]&&num1[0]==num[6]))) {//8 area2=Math.abs((num1[2]-num[8])*(num1[5]-num[9])-(num1[4]-num[8])*(num1[3]-num[9]))*0.5; } else if(count3==2&&((num1[2]-num[6])*(num1[2]-num[4])>0||(num1[2]==num[6]&&num1[2]==num[4])||(num1[2]==num[6]&&num1[2]==num[8])||(num1[2]==num[4]&&num1[2]==num[8]))) {//6 area2=Math.abs((num1[0]-num[6])*(num1[5]-num[7])-(num1[4]-num[6])*(num1[1]-num[7]))*0.5; } area3=Math.abs(area1-area2); area2=area1-area3; if(area2>=area3) outPut("2 "+df.format(area3)+" "+df.format(area2)); else outPut("2 "+df.format(area2)+" "+df.format(area3)); } }//b else if(num[6]==num[8]) {//c num1[0]=(num[5]-k2*num[4]-num[1]+k1*num[0])/(k1-k2);//k2 num1[1]=(k1*(num[5]-k2*num[4])+k2*(-num[1]+k1*num[0]))/(k1-k2); num1[2]=(num[1]-k1*num[0]-num[5]+k3*num[4])/(k3-k1);//k3 num1[3]=(k3*(num[1]-k1*num[0])+k1*(-num[5]+k3*num[4]))/(k3-k1); num1[4]=num[6]; num1[5]=k1*(num[6]-num[0])+num[1];//k4 for(int j=0;j<3;j++) { max[j]=getMax(num[4+j],num[6+j]); min[j]=getMin(num[4+j],num[6+j]); maxy[j]=getMax(num[5+j],num[7+j]); miny[j]=getMin(num[5+j],num[7+j]); } for(int j=0;j<5;j=j+2) { if((num1[j]-num[4]==0&&num1[j+1]<=maxy[2]&&num1[j+1]>=miny[2])||(num1[j]-num[6]==0&&num1[j+1]<=maxy[2]&&num1[j+1]>=miny[2])||(num1[j]-num[8]==0&&num1[j+1]<=maxy[2]&&num1[j+1]>=miny[2])){ count=1; count1=count2=count3=1; break; } }//, for(int j=0;j<5;j=j+2) { if(((num1[j]-num[4])*(num1[j]-num[6])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[7])<0||(num1[j]-num[4])*(num1[j]-num[8])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<=0)&&count1!=2){//4 count1++; } if(((num1[j]-num[4])*(num1[j]-num[8])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<0||(num1[j+1]-num[9])*(num1[j+1]-num[7])<0)&&count2!=2) {//8 count2++; } if(((num1[j]-num[4])*(num1[j]-num[6])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[7])<0||(num1[j+1]-num[9])*(num1[j+1]-num[7])<0)&&count3!=2) {//6 count3++; } } count=findMax(count1,count2,count3); if(count<2) outPut(String.valueOf(count)); else { area1=getArea(circu,l1,l2,l3); if(count1==2&&((num1[4]-num[8])*(num1[4]-num[6])>0||(num1[4]==num[8]&&num1[4]==num[6])||(num1[4]==num[4]&&num1[4]==num[6])||(num1[4]==num[4]&&num1[4]==num[8]))) {//4 area2=0.5*Math.abs((num1[3]-num[5])*(num1[0]-num[4])-(num1[2]-num[4])*(num1[1]-num[5])); } else if(count2==2&&((num1[0]-num[4])*(num1[0]-num[8])>0||(num1[0]==num[4]&&num1[0]==num[8])||(num1[0]==num[6]&&num1[0]==num[8])||(num1[0]==num[4]&&num1[0]==num[6]))) {//8 area2=Math.abs((num1[2]-num[8])*(num1[5]-num[9])-(num1[4]-num[8])*(num1[3]-num[9]))*0.5; } else if(count3==2&&((num1[2]-num[6])*(num1[2]-num[4])>0||(num1[2]==num[6]&&num1[2]==num[4])||(num1[2]==num[6]&&num1[2]==num[8])||(num1[2]==num[4]&&num1[2]==num[8]))) {//6 area2=Math.abs((num1[0]-num[6])*(num1[5]-num[7])-(num1[4]-num[6])*(num1[1]-num[7]))*0.5; } area3=Math.abs(area1-area2); area2=area1-area3; if(area2>=area3) outPut("2 "+df.format(area3)+" "+df.format(area2)); else outPut("2 "+df.format(area2)+" "+df.format(area3)); } }//c else {//d num1[0]=(num[5]-k2*num[4]-num[1]+k1*num[0])/(k1-k2);//k2 num1[1]=(k1*(num[5]-k2*num[4])+k2*(-num[1]+k1*num[0]))/(k1-k2); num1[2]=(num[1]-k1*num[0]-num[5]+k3*num[4])/(k3-k1);//k3 num1[3]=(k3*(num[1]-k1*num[0])+k1*(-num[5]+k3*num[4]))/(k3-k1); num1[4]=(num[1]-k1*num[0]-num[7]+k4*num[6])/(k4-k1);//k4 num1[5]=(k4*(num[1]-k1*num[0])+k1*(-num[7]+k4*num[6]))/(k4-k1); for(int j=0;j<3;j++) { max[j]=getMax(num[4+j],num[6+j]); min[j]=getMin(num[4+j],num[6+j]); maxy[j]=getMax(num[5+j],num[7+j]); miny[j]=getMin(num[5+j],num[7+j]); } if(k1==k2||k1==k3||k1==k4) { if(k1==k2) n=0; else if(k1==k3) n=2; else if(k1==k4) n=4; for(int j=0;j<5;j=j+2) { if(j==n) continue; if((num1[j]-num[4]==0&&num1[j+1]<=maxy[0]&&num1[j+1]>=miny[0])||(num1[j]-num[6]==0&&num1[j+1]<=maxy[1]&&num1[j+1]>=miny[1])||(num1[j]-num[8]==0&&num1[j+1]<=maxy[2]&&num1[j+1]>=miny[2])){ count=1; count1=count2=count3=1; break; } } for(int j=0;j<5;j=j+2) {//4:0,0 -4,4 -2,0 2,0 0,2 if(j==n) continue; if((((num1[j]-num[4])*(num1[j]-num[6])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[7])<0)||((num1[j]-num[4])*(num1[j]-num[8])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<0))&&count1!=2){//4 count1++; } if((((num1[j]-num[4])*(num1[j]-num[8])<0&&((num1[j+1]-num[5])*(num1[j+1]-num[9])<0)||((num1[j]-num[8])*(num1[j]-num[6])<0)&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<0))&&count2!=2) {//8 count2++; } if((((num1[j]-num[4])*(num1[j]-num[6])<0&&((num1[j+1]-num[5])*(num1[j+1]-num[7])<0)||((num1[j]-num[8])*(num1[j]-num[6])<0)&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<0))&&count3!=2) {//6 count3++; } } count=findMax(count1,count2,count3); if(count<2) outPut(String.valueOf(count)); else { area1=getArea(circu,l1,l2,l3); if(count1==2&&((num1[4]-num[8])*(num1[4]-num[6])>0||(num1[4]==num[8]&&num1[4]==num[6])||(num1[4]==num[4]&&num1[4]==num[6])||(num1[4]==num[8]&&num1[4]==num[6]))) {//4 area2=0.5*Math.abs((num1[3]-num[5])*(num1[0]-num[4])-(num1[2]-num[4])*(num1[1]-num[5])); } else if(count2==2&&((num1[0]-num[4])*(num1[0]-num[8])>0||(num1[0]==num[4]&&num1[0]==num[8])||(num1[0]==num[6]&&num1[0]==num[8])||(num1[0]==num[4]&&num1[0]==num[8]))) {//8 area2=Math.abs((num1[2]-num[8])*(num1[5]-num[9])-(num1[4]-num[8])*(num1[3]-num[9]))*0.5; } else if(count3==2&&((num1[2]-num[6])*(num1[2]-num[4])>0||(num1[2]==num[6]&&num1[2]==num[4])||(num1[2]==num[6]&&num1[2]==num[8])||(num1[2]==num[4]&&num1[2]==num[8]))) {//6 area2=Math.abs((num1[0]-num[6])*(num1[5]-num[7])-(num1[4]-num[6])*(num1[1]-num[7]))*0.5; } area3=area1-area2; if(area2>=area3) outPut("2 "+df.format(area3)+" "+df.format(area2)); else outPut("2 "+df.format(area2)+" "+df.format(area3)); } } else{ for(int j=0;j<5;j=j+2) { if((num1[j+1]==num[5]&&num1[j]<=max[0]&&num1[j]>=min[0])||(num1[j+1]==num[7]&&num1[j]<=max[1]&&num1[j]>=min[1])||(num1[j+1]==num[9]&&num1[j]<=max[2]&&num1[j]>=min[2])){ eq=true; } if((num1[j]-num[4]==0&&num1[j+1]<=maxy[0]&&num1[j+1]>=miny[0])||(num1[j]-num[6]==0&&num1[j+1]<=maxy[1]&&num1[j+1]>=miny[1])||(num1[j]-num[8]==0&&num1[j+1]<=maxy[2]&&num1[j+1]>=miny[2]) ||(num1[j+1]==num[5]&&num1[j]<=max[0]&&num1[j]>=min[0])||(num1[j+1]==num[7]&&num1[j]<=max[1]&&num1[j]>=min[1])||(num1[j+1]==num[9]&&num1[j]<=max[2]&&num1[j]>=min[2]) ){ count=1; if(k2==0) {//4==6 count1++; count3++; } else if(k3==0) {//4==8 count1++; count2++; } else if(k4==0) {//6==8 count3++; count2++; } n=j; break; } }//, for(int j=0;j<5;j=j+2) { if(j==n) continue; if(eq) { if(((num1[j]-num[4])*(num1[j]-num[6])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[7])<=0||(num1[j]-num[4])*(num1[j]-num[8])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<=0)&&count1!=2){//4 count1++; } if(((num1[j]-num[4])*(num1[j]-num[8])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<=0||(num1[j]-num[8])*(num1[j]-num[6])<0&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<=0)&&count2!=2) {//8 count2++; } if(((num1[j]-num[4])*(num1[j]-num[6])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[7])<=0||(num1[j]-num[8])*(num1[j]-num[6])<0&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<=0)&&count3!=2) {//6 count3++; } } else { if(((num1[j]-num[4])*(num1[j]-num[6])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[7])<0||(num1[j]-num[4])*(num1[j]-num[8])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<0)&&count1!=2){//4 count1++; } if(((num1[j]-num[4])*(num1[j]-num[8])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[9])<0||(num1[j]-num[8])*(num1[j]-num[6])<0&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<0)&&count2!=2) {//8 count2++; } if(((num1[j]-num[4])*(num1[j]-num[6])<0&&(num1[j+1]-num[5])*(num1[j+1]-num[7])<0||(num1[j]-num[8])*(num1[j]-num[6])<0&&(num1[j+1]-num[9])*(num1[j+1]-num[7])<0)&&count3!=2) {//6 count3++; } } } count=findMax(count1,count2,count3); if(count<2) outPut(String.valueOf(count)); else { area1=getArea(circu,l1,l2,l3); if(count1==2&&((num1[4]-num[8])*(num1[4]-num[6])>0||(num1[4]==num[8]&&num1[4]==num[6])||(num1[4]==num[4]&&num1[4]==num[6]))) {//4 area2=0.5*Math.abs((num1[3]-num[5])*(num1[0]-num[4])-(num1[2]-num[4])*(num1[1]-num[5])); } else if(count2==2&&((num1[0]-num[4])*(num1[0]-num[8])>0||(num1[0]==num[4]&&num1[0]==num[8])||(num1[0]==num[6]&&num1[0]==num[8]))) {//8 area2=Math.abs((num1[2]-num[8])*(num1[5]-num[9])-(num1[4]-num[8])*(num1[3]-num[9]))*0.5; } else if(count3==2&&((num1[2]-num[6])*(num1[2]-num[4])>0||(num1[2]==num[6]&&num1[2]==num[4])||(num1[2]==num[6]&&num1[2]==num[8]))) {//6 area2=Math.abs((num1[0]-num[6])*(num1[5]-num[7])-(num1[4]-num[6])*(num1[1]-num[7]))*0.5; } area3=area1-area2; if(area2>=area3) outPut("2 "+df.format(area3)+" "+df.format(area2)); else outPut("2 "+df.format(area2)+" "+df.format(area3)); } } }//d } } }//3 } } else outPut("Wrong Format"); } else if(i<str1.length()&&more) { int j=1; while(i<str1.length()) { if(j%2!=0) { if(i<str1.length()) { t=circle(i,str1,' '); num[9]=Double.parseDouble(str1.substring(i, t)); i=t+1; if(i==str1.length()) { outPut("Wrong Format"); } } else outPut("Wrong Format"); } else { if(i<str1.length()) { t=circle(i,str1,','); num[9]=Double.parseDouble(str1.substring(i, t)); i=t+1; if(i==str1.length()) { outPut("Wrong Format"); } } else outPut("Wrong Format"); } j++; } outPut("wrong number of points");//数量不符合 } else outPut("Wrong Format"); } } else outPut("Wrong Format"); } public static void choice(String str1,int c) { double [] num = new double[6]; boolean more=false; if(str1.charAt(1)==':') { int i=2,t=0,m=1; if(i==str1.length()) outPut("Wrong Format"); else if(i<str1.length()) { for(int j=0;j<5;j++) { if(m%2!=0&&i<str1.length()) { t=circle(i,str1,','); } else if(m%2==0&&i<str1.length()){ t=circle(i,str1,' '); } else outPut("Wrong Format"); if(isDouble(str1.substring(i, t))) { num[j]=Double.parseDouble(str1.substring(i, t)); i=t+1; } else outPut("Wrong Format"); if(t==str1.length()) outPut("wrong number of points"); m++; } while((t+1)<str1.length()) { if(str1.charAt(t+1)==',') { more=true; break; } t++; } t=i-1; if(i<str1.length()&&!more) { t=circle(i,str1,'\0'); if(isDouble(str1.substring(i, t))==true) { num[5]=Double.parseDouble(str1.substring(i, t)); if(t==str1.length()) { double l1,l2,l3; l1=Math.sqrt(Math.pow(num[0]-num[2],2 )+Math.pow(num[1]-num[3], 2)); l2=Math.sqrt(Math.pow(num[0]-num[4],2 )+Math.pow(num[1]-num[5], 2)); l3=Math.sqrt(Math.pow(num[4]-num[2],2 )+Math.pow(num[5]-num[3], 2)); if(c==1) { if(l1+l2-l3<0.01||l2+l3-l1<0.01||l1+l3-l2<0.01) outPut("data error"); else { if(l1==l2||l2==l3||l1==l3) { System.out.print("true "); } else System.out.print("false "); if(l1==l2&&l2==l3) outPut("true"); else outPut("false"); } } else if(c==2) { DecimalFormat df = new DecimalFormat("0.0#####"); double circu,area,core; if(l1+l2-l3<0.01||l2+l3-l1<0.01||l1+l3-l2<0.01) outPut("data error"); else { circu=l1+l2+l3; area=getArea(circu,l1,l2,l3); outPut(df.format(circu)+" "+df.format(area)+" "+df.format((num[0]+num[2]+num[4])/3)+","+df.format((num[1]+num[3]+num[5])/3)); } } else if(c==3) { if(l1+l2-l3<0.01||l2+l3-l1<0.01||l1+l3-l2<0.01) outPut("data error"); else { double cos1,cos2,cos3; cos1=l2*l2+l3*l3-l1*l1; cos2=l1*l1+l3*l3-l2*l2; cos3=l1*l1+l2*l2-l3*l3; if(cos1<-0.01||cos2<-0.01||cos3<-0.01) { outPut("true false false"); } else if(cos1<0.01||cos2<0.01||cos3<0.01) { outPut("false true false"); } else if(cos1>0&&cos2>0&&cos3>0){ outPut("false false true"); } } } } } else outPut("Wrong Format"); } else if(i<str1.length()&&more) { int j=1; while(i<str1.length()) { if(j%2!=0) { if(i<str1.length()) { t=circle(i,str1,' '); num[5]=Double.parseDouble(str1.substring(i, t)); i=t+1; if(i==str1.length()) { outPut("Wrong Format"); } } else outPut("Wrong Format"); } else { if(i<str1.length()) { t=circle(i,str1,','); num[5]=Double.parseDouble(str1.substring(i, t)); i=t+1; if(i==str1.length()) { outPut("Wrong Format"); } } else outPut("Wrong Format"); } j++; } outPut("wrong number of points");//数量不符合 } else outPut("Wrong Format"); } } else outPut("Wrong Format"); } public static int circle(int i,String str,char a) { int t=i+1,t1=0; for(int j=i;j<str.length()-1;j++) { if(str.charAt(j)=='-'||str.charAt(j)=='+') {//1 if(str.charAt(j+1)<=57&&str.charAt(j+1)>=48&&!(str.charAt(j+1)==48&&(str.charAt(j+2)<=57&&str.charAt(j+2)>=48))) {//a for(int k=j+1;k<str.length()&&str.charAt(k)!=a;k++) {//a1 if(str.charAt(j)=='.') { t1++; } if(str.charAt(k)==','||str.charAt(k)=='.'&&!(str.charAt(k+1)<=57&&str.charAt(k+1)>=48)) { outPut("Wrong Format"); } t=k; }//a1 }//a else if(t1>1||!(str.charAt(j+1)<=57&&str.charAt(j+1)>=48)||str.charAt(j+1)==48&&(str.charAt(j+2)<=57&&str.charAt(j+2)>=48)) outPut("Wrong Format");//b return t+1; }//1 else if(str.charAt(j)<=57&&str.charAt(j)>=48&&!(str.charAt(j)==48&&(str.charAt(j+1)<=57&&str.charAt(j+1)>=48))) {//2 for(int k=j;k<str.length()&&str.charAt(k)!=a;k++) {//c1 if(str.charAt(k)=='.') { t1++; } if(str.charAt(k)==','||str.charAt(k)=='.'&&!(str.charAt(k+1)<=57&&str.charAt(k+1)>=48)) { outPut("Wrong Format"); } t=k; }//c1 if(t1>1) outPut("Wrong Format"); return t+1; }//2 else { outPut("Wrong Format");//3 } } return t; } public static void outPut(String str) { System.out.println(str); System.exit(0); } public static boolean isDouble(String str) { try { Double num = Double.parseDouble(str); } catch(NumberFormatException e){ return false; } return true; } public static double getArea(double circu,double l1,double l2,double l3) { return Math.sqrt(circu/2*(circu/2-l1)*(circu/2-l2)*(circu/2-l3)); } public static int findMax(int a,int b,int c) { int max=a; if(max<b) max=b; if(max<c) max=c; return max; } public static double getMax(double a,double b) { if(a>=b) return a; else return b; } public static double getMin(double a,double b) { if(a<=b) return a; else return b; } }
(1)设计与分析:选项1、2、3比较简单,可以通过求三边的长度,根据数学相关的知识来判断选项1、2、3的要求,可以很快实现选项1、2、3的要求;选项4可以把直线与三角形三边交点(可能不在线段上,而是在延长线的交点)求出来,可以得到3个点,这3个交点依次与三角形的对应边所在的线段两端的x坐标值相减,然后再相乘,若为正数则交点不在线段上,反之,在线段上,以此来统计交点的数量,若为2个交点(一定被分成了一个小三角形和另一个图形),再用海伦公式来计算三角形的面积;选项5,射线需要给定一个方向,然后再与三角求交点,交点的判断方法用选项4中的。
(2)踩坑心得:1.判断是否为三角形需要考虑精度问题:
2.注意输出格式中的要求,可以采用DecimalFormat df = new DecimalFormat("0.0#####"),来实现题目要求
(3)改进建议:对于一些重复的代码,例如求交点,可以用一个方法来实现,此外,求交点也可以采用叉乘来判断。
2.题目集06 7-2

输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
类图:

import java.text.DecimalFormat; import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自动生成的方法存根 DecimalFormat df = new DecimalFormat("0.0##"); Scanner in = new Scanner(System.in); String str = in.nextLine(); String str1; String regex = "[\\-\\+]?\\d+(\\.\\d+)?,[\\-\\+]?\\d+(\\.\\d+)?(\\s[\\-\\+]?\\d+(\\.\\d+)?,[\\-\\+]?\\d+(\\.\\d+)?\\s?){0,}"; if(str.length()>2) { str1 = str.substring(0, 1); str=str.substring(2, str.length()); if(str.matches(regex)) {// 符合格式 String[] s = str.split(",|\\s"); for(int i=0; i<s.length; i++){ if(s[i].matches("0\\d+")) outPut("Wrong Format"); } double [] num = new double[12]; for(int i=0; i<12&&i<s.length; i++) { num[i] = Double.parseDouble(s[i]); } if(0<Integer.parseInt(str1)&&Integer.parseInt(str1)<4 ){// 选项1,2,3 if(s.length==8) { if(isRepetition(num)) outPut("points coincide"); else { double l1,l2,l3,l4,l; l1=Math.sqrt(Math.pow(num[0]-num[2], 2)+Math.pow(num[1]-num[3], 2)); l2=Math.sqrt(Math.pow(num[2]-num[4], 2)+Math.pow(num[3]-num[5], 2)); l3=Math.sqrt(Math.pow(num[4]-num[6], 2)+Math.pow(num[5]-num[7], 2)); l4=Math.sqrt(Math.pow(num[0]-num[6], 2)+Math.pow(num[1]-num[7], 2)); l=Math.sqrt(Math.pow(num[0]-num[4], 2)+Math.pow(num[1]-num[5], 2)); switch (Integer.parseInt(str1) ) { case 1:choice1(num,l1,l2,l3,l4,l);// 选项1 break; case 2:choice2(num,l1,l2,l3,l4,l);// 选项2 break; case 3:choice3(num,l1,l2,l3,l4,l);// 选项3 break; } } } else outPut("wrong number of points"); } else if(Integer.parseInt(str1)==4) {// 选项4 if(s.length==12) { if(num[0]==num[2]&&num[1]==num[3]) outPut("points coincide");// 前两个坐标重合 else choice4(num); } else outPut("wrong number of points"); } else if(Integer.parseInt(str1)==5) {// 选项5 if(s.length==10) choice5(num); else outPut("wrong number of points"); } else outPut("Wrong Format"); } else outPut("Wrong Format");// 不符合格式 } else outPut("Wrong Format"); // 字符串长度不够<2 } public static boolean isRepetition(double []num) {// 选项1,2,3是否有重复的点 for(int i=0; i<5; i=i+2) { if((num[i]==num[i+2]&&num[i+1]==num[i+3])||(num[0]==num[6]&&num[1]==num[7])) { return true; } } return false; } public static void outPut(String str) { System.out.println(str); System.exit(0); } public static int isQuad(double []n) { double t1,t2,t3,t4; t1=(n[2]-n[0])*(n[5]-n[3])-(n[4]-n[2])*(n[3]-n[1]); t2=(n[4]-n[2])*(n[7]-n[5])-(n[6]-n[4])*(n[5]-n[3]); t3=(n[6]-n[4])*(n[1]-n[7])-(n[0]-n[6])*(n[7]-n[5]); t4=(n[0]-n[6])*(n[3]-n[1])-(n[2]-n[0])*(n[1]-n[7]); if( (t1*t2>0)&&(t2*t3>0)&&(t3*t4>0)) return 1; else if(t1*t2*t3*t4<0) return 2; else if((t1==t4&&t4==0&&t2*t3>0)||(t1==t2&&t2==0&&t3*t4>0)||(t2==t3&&t3==0&&t1*t4>0)||(t3==t4&&t4==0&&t1*t2>0)||(t2==t4&&t2==0&&t1*t3!=0)||(t1==0&&t2*t3*t4!=0) ||(t2==0&&t1*t3*t4!=0)||(t3==0&&t2*t1*t4!=0)||(t4==0&&t2*t3*t1!=0)) return 0; else return -1; } public static double getMax(double []n) { return Math.max(Math.max(n[0], n[2]), Math.max(n[4], n[6])); } public static double getMin(double []n) { return Math.min(Math.min(n[0], n[2]), Math.min(n[4], n[6])); } public static double getMax(double n1 ,double n2) { return Math.max(n1, n2); } public static double getMin(double n1,double n2) { return Math.min(n1, n2); } public static double getArea(double l1, double l2, double l3) { double c=(l1+l2+l3)/2; return Math.sqrt(c*(c-l1)*(c-l2)*(c-l3)); } public static void choice1(double[]n,double l1,double l2,double l3,double l4,double l) { if(isQuad(n)>0) { if((n[0]-n[2])*(n[1]-n[5])==(n[6]-n[4])*(n[1]-n[3])&&(Math.abs(l1-l3)<0.001)) outPut("true true"); else outPut("true false"); } else outPut("false false"); } public static void choice2(double[] n, double l1, double l2, double l3, double l4, double l) { if(isQuad(n)>0) {// 四边形 if((n[0]-n[2])*(n[7]-n[5])==(n[6]-n[4])*(n[1]-n[3])&&(Math.abs(l1-l3)<0.001)) {// 平行四边形 if(l1!=l2&&Math.abs(l1*l1+l2*l2-l*l)<0.01) outPut("false true false"); else if(l1==l2&&Math.abs(l1*l1+l2*l2-l*l)<0.001) outPut("true true true"); else if(l1==l2) outPut("true false false"); else outPut("false false false"); } else outPut("false false false"); } else outPut("not a quadrilateral"); } public static void choice3(double[] n, double l1, double l2, double l3, double l4, double l) { DecimalFormat df = new DecimalFormat("0.0##"); if(isQuad(n)==1){ outPut("true "+df.format(l1+l2+l3+l4)+" "+df.format(0.5*Math.abs((n[0]-n[4])*(n[3]-n[7])-(n[2]-n[6])*(n[1]-n[5])) ) ); } else if(isQuad(n)==2){ outPut("false "+df.format(l1+l2+l3+l4)+" "+df.format(0.5*Math.abs((n[0]-n[4])*(n[3]-n[7])-(n[2]-n[6])*(n[1]-n[5])) ) ); } else outPut("not a quadrilateral"); } public static void choice4(double[] n) { double[] m=new double[8]; for(int i=0; i<8;i++) { m[i]=n[i+4]; } if(isQuad(m)<0) outPut("not a quadrilateral or triangle"); else if(isQuad(m)==1){ if(((n[2]-n[0])*(m[3]-m[1])==(m[2]-m[0])*(n[3]-n[1])&&(m[0]-n[0])*(n[3]-n[1])==(n[2]-n[0])*(m[1]-n[1]))|| ((n[2]-n[0])*(m[3]-m[5])==(m[2]-m[4])*(n[3]-n[1])&&(m[2]-n[0])*(n[3]-n[1])==(n[2]-n[0])*(m[3]-n[1]))|| ((n[2]-n[0])*(m[5]-m[7])==(m[4]-m[6])*(n[3]-n[1])&&(m[4]-n[0])*(n[3]-n[1])==(n[2]-n[0])*(m[5]-n[1]))|| ((n[2]-n[0])*(m[7]-m[1])==(m[6]-m[0])*(n[3]-n[1])&&(m[0]-n[0])*(n[3]-n[1])==(n[2]-n[0])*(m[1]-n[1]))) outPut("The line is coincide with one of the lines"); else { if(n[0]==n[2]) {// 垂直x轴 if(n[0]<getMin(m)||n[0]>getMax(m)) outPut("0"); else if(n[0]==getMin(m)||n[0]==getMax(m)) outPut("1");} else outPut("1"); } } else { int i=0; double area1,area2,area3; if(isQuad(m)==0) { if(((n[2]-n[0])*(m[3]-m[1])==(m[2]-m[0])*(n[3]-n[1])&&(m[0]-n[0])*(n[3]-n[1])==(n[2]-n[0])*(m[1]-n[1]))|| ((n[2]-n[0])*(m[3]-m[5])==(m[2]-m[4])*(n[3]-n[1])&&(m[2]-n[0])*(n[3]-n[1])==(n[2]-n[0])*(m[3]-n[1]))|| ((n[2]-n[0])*(m[5]-m[7])==(m[4]-m[6])*(n[3]-n[1])&&(m[4]-n[0])*(n[3]-n[1])==(n[2]-n[0])*(m[5]-n[1]))|| ((n[2]-n[0])*(m[7]-m[1])==(m[6]-m[0])*(n[3]-n[1])&&(m[0]-n[0])*(n[3]-n[1])==(n[2]-n[0])*(m[1]-n[1]))) outPut("The line is coincide with one of the lines"); else { if(n[0]==n[2]) {// 垂直x轴 if(n[0]<getMin(m)||n[0]>getMax(m)) outPut("0"); else if(n[0]==getMin(m)||n[0]==getMax(m)) outPut("1");} outPut("1"); } } } } public static void choice5(double[]n ) { double[] m=new double[8]; for(int i=0; i<8;i++) { m[i]=n[i+2]; } if(isQuad(m)<0) outPut("not a quadrilateral or triangle"); else { double t1,t2,t3,t4; t1=(n[0]-m[0])*(m[3]-m[1])-(m[2]-m[0])*(n[1]-m[1]); t2=(n[0]-m[2])*(m[5]-m[3])-(m[4]-m[2])*(n[1]-m[3]); t3=(n[0]-m[4])*(m[7]-m[5])-(m[6]-m[4])*(n[1]-m[5]); t4=(n[0]-m[6])*(m[1]-m[7])-(m[0]-m[6])*(n[1]-m[7]); if(isQuad(m)==0) { if(m[0]==m[2]&&m[1]==m[3]) { if(t1==0&&t2*t3>0&&t3*t4>0) outPut("in the triangle"); else if(t1==0&&t2*t3*t4==0&&(t2*t3>=0||t2*t4>=0||t3*t4>=0) ) outPut("on the triangle"); else outPut("outof the triangle"); } else if(m[2]==m[4]&&m[3]==m[5]) { if(t2==0&&t1*t3>0&&t1*t4>0) outPut("in the triangle"); else if(t2==0&&t1*t3*t4==0&&(t1*t3>=0||t1*t4>=0||t3*t4>=0))outPut("on the triangle"); else outPut("outof the triangle"); } else if(m[4]==m[6]&&m[5]==m[7]) { if(t3==0&&t1*t2>0&&t1*t4>0) outPut("in the triangle"); else if(t3==0&&t1*t2*t4==0&&(t2*t1>=0||t2*t4>=0||t1*t4>=0))outPut("on the triangle"); else outPut("outof the triangle"); } else if(m[0]==m[6]&&m[1]==m[7]) { if(t4==0&&t1*t3>0&&t1*t2>0) outPut("in the triangle"); else if(t4==0&&t1*t3*t2==0&&(t2*t3>=0||t2*t1>=0||t3*t1>=0))outPut("on the triangle"); else outPut("outof the triangle"); } else{ if((t1*t2>0)&&(t2*t3>0)&&(t3*t4>0)) outPut("in the triangle"); else if( (t1*t2*t3*t4==0&&(n[0]<=getMax(m[0],m[2])&&n[0]>=getMin(m[0],m[2])&&n[1]<=getMax(m[1],m[3])&&n[1]>=getMin(m[1],m[3])||n[0]<=getMax(m[4],m[2])&&n[0]>=getMin(m[4],m[2])&&n[1]<=getMax(m[5],m[3])&&n[1]>=getMin(m[5],m[3])|| n[0]<=getMax(m[4],m[6])&&n[0]>=getMin(m[4],m[6])&&n[1]<=getMax(m[5],m[7])&&n[1]>=getMin(m[5],m[7])||n[0]<=getMax(m[0],m[6])&&n[0]>=getMin(m[0],m[6])&&n[1]<=getMax(m[1],m[7])&&n[1]>=getMin(m[1],m[7]) ) ) )outPut("on the triangle"); else outPut("outof the triangle"); } } else { if((t1*t2>0)&&(t2*t3>0)&&(t3*t4>0)) outPut("in the quadrilateral"); else if((t1*t2*t3*t4==0&&(n[0]<=getMax(m[0],m[2])&&n[0]>=getMin(m[0],m[2])&&n[1]<=getMax(m[1],m[3])&&n[1]>=getMin(m[1],m[3])||n[0]<=getMax(m[4],m[2])&&n[0]>=getMin(m[4],m[2])&&n[1]<=getMax(m[5],m[3])&&n[1]>=getMin(m[5],m[3])|| n[0]<=getMax(m[4],m[6])&&n[0]>=getMin(m[4],m[6])&&n[1]<=getMax(m[5],m[7])&&n[1]>=getMin(m[5],m[7])||n[0]<=getMax(m[0],m[6])&&n[0]>=getMin(m[0],m[6])&&n[1]<=getMax(m[1],m[7])&&n[1]>=getMin(m[1],m[7]) ) ) ) outPut("on the quadrilateral");//(t1==t2&&t1==0&&t3*t4>0)||(t1==t3&&t1==0&&t2*t4>0)||(t1==t4&&t4==0&&t2*t3>0)||(t2==t3&&t2==0&&t1*t4>0)||(t2==t4&&t2==0&&t1*t3>0)||(t3==t4&&t4==0&&t1*t2>0)||(t1==t2&&t2==t3&&t3==0)||(t1==t2&&t2==t4&&t4==0)||(t1==t4&&t4==t3&&t3==0)||(t4==t2&&t2==t3&&t3==0) else outPut("outof the quadrilateral"); } } } }
(1)设计与分析:由于选项多次出现了四边形,因此可以创建一个方法来判断凹凸四边形及三角形,可以将四个点的坐标都传入方法中,返回一个整数,以此来判断,由于题目中给出了输入是按照一定的顺序(顺时针或逆时针),因此可以采用叉乘(具体看代码中的方法 isQuad(double []n))来判断,若不是按照顺序不可以这样直接判断,先判断是否为四边形再判断是否为平行四边形,最后再根据各种图形的数学上的关系来判断。
(2)踩坑心得:采用正则表达式可以减少判断格式的代码数量,不要在采用线段长度来判断是否为四边形(即两边与对角线构成三角形),这种方法存在问题,有些错误情况会被认为四边形。
(3)改进建议:
3.超星链表作业
在单链表基础上改写代码,实现双向链表数据结构:
public class Node<E> {
private E data;//数据域,类型为泛型E
private Node<E> next;//后继引用(指针)
private Node<E> previous;//前驱引用(指针)
}
public interface DoubleLinkedListImpl<E> {
/**
* 判断链表是否为空
* @return
*/
public boolean isEmpty();
/**
* 获取当前链表节点数量
* @return 节点数
*/
public int getSize();
/**
* 获取链表中第index个位置的节点的data值
* @param index:节点在链表中的位置
* @return:返回该节点的data值
*/
public E getData(int index);
/**
* 删除链表最后一个节点
*/
public void remove();
/**
*删除链表中第index位置的节点
* @param index:节点在链表中的位置
*/
public void remove(int index);
/**
* 在链表的第index个位置之前插入一个节点,值为theElement,index∈[1,size]
* @param index:插入节点在链表中的位置
* @param theElement:新插入节点的data值
*/
public void add(int index, E theElement);
/**
* 在链表尾插入节点,插入节点data值为element
* @param element
*/
public void add(E element);
/**
* 输出链表
*/
public void printList();
/**
* 获取第一个节点的data值
* @return
*/
public E getFirst();
/**
* 获取链表最后一个节点的data值
* @return
*/
public E getLast();
}
public class DoubleLinkedList<E> implements DoubleLinkedListImpl<E> {
private Node<E> head;//头结点,非第一个节点
private Node<E> curr;//当前节点
private Node<E> tail;//最后一个节点
private int size;//当前链表节点数
......
}
1 package DoubleLinkedList; 2 3 4 public class Main { 5 6 public static void main(String[] args) { 7 // TODO 自动生成的方法存根 8 DoubleLinkedList<String> list = new DoubleLinkedList<String> (); 9 list.add("a"); 10 list.add("b"); 11 list.add("c"); 12 list.printList(); 13 System.out.println(list.isEmpty()); 14 list.add(1, "efgh");// 从1开始 15 list.printList(); 16 System.out.println(list.getData(2)); 17 list.remove();// 从1开始 18 list.printList(); 19 list.remove(1);// 从1开始 20 list.printList(); 21 } 22 23 } 24 25 class DoubleLinkedList<E> implements DoubleLinkedListImpl<E>{ 26 27 private Node<E> head = new Node<E>(); 28 private Node<E> curr = new Node<E>(); 29 private Node<E> tail = new Node<E>(); 30 private Node<E> previous = new Node<E>(); 31 32 private int size = 0; 33 34 35 public DoubleLinkedList() { 36 super(); 37 // TODO 自动生成的构造函数存根 38 } 39 40 @Override 41 public boolean isEmpty() { 42 // TODO 自动生成的方法存根 43 if(size<=0) return false; 44 else return true; 45 46 } 47 48 @Override 49 public int getSize() {// 返回链表节点数 50 // TODO 自动生成的方法存根 51 return this.size; 52 } 53 54 @Override 55 public E getData(int index) { 56 // TODO 自动生成的方法存根 57 if(index<=0||index>size) { 58 System.out.println("访问错误!"); 59 return null; 60 } 61 else { 62 curr = head; 63 for(int i = 1; i<index; i++) { 64 curr = curr.getNext(); 65 } 66 return curr.getO(); 67 } 68 } 69 // 删除链表最后一个节点 70 @Override 71 public void remove() { 72 // TODO 自动生成的方法存根 73 if(size<=0) System.out.println("未存入元素!"); 74 else if(size==1) { 75 head = null; 76 size--; 77 } 78 else if(size>1) { 79 curr = head; 80 for(int i =1; i<size-1; i++) { 81 curr = curr.getNext(); 82 } 83 curr.getNext().setPrevious(null); 84 curr.setNext(null); 85 size--; 86 } 87 88 } 89 //删除链表中第index位置的节点 90 @Override 91 public void remove(int index) { 92 // TODO 自动生成的方法存根 93 if(index<=0||index>size) System.out.println("访问错误!"); 94 else if(index==1) { 95 head.getNext().setPrevious(null); 96 head = head.getNext(); 97 size--; 98 } 99 else if(index==size){ 100 curr = head; 101 for(int i=1; i<index-1; i++) { 102 curr = curr.getNext(); 103 } 104 curr.getNext().setPrevious(null); 105 curr.setNext(null); 106 size--; 107 } 108 else { 109 curr = head; 110 for(int i = 1; i<index-1; i++) { 111 curr = curr.getNext(); 112 } 113 curr.setNext(curr.getNext().getNext()); 114 curr.getNext().setPrevious(null); 115 curr.getNext().getNext().setPrevious(curr); 116 size--; 117 } 118 119 } 120 121 // 在链表的第index个位置之前插入一个节点,值为theElement,index∈[1,size] 122 @Override 123 public void add(int index, E theElement) { 124 // TODO 自动生成的方法存根 125 if(index<0||index>size) System.out.println("访问错误!"); 126 else if(index==1) { 127 Node <E> temp = new Node<E>(); 128 temp.setO(theElement); 129 temp.setNext(head); 130 head.setPrevious(temp); 131 head = temp; 132 size++; 133 } 134 else if(index>1) { 135 Node<E> temp = new Node<E>(); 136 temp.setO(theElement); 137 curr = head; 138 for(int i = 1; i<index; i++) { 139 curr = curr.getNext(); 140 } 141 temp.setNext(curr.getNext()); 142 curr.getNext().setPrevious(temp); 143 curr.setNext(temp); 144 temp.setPrevious(curr); 145 size++; 146 } 147 148 } 149 // 在链表尾插入节点,插入节点data值为element 150 @Override 151 public void add(E element) { 152 // TODO 自动生成的方法存根 153 if(size==0) { 154 head.setO(element); 155 head.setNext(null); 156 head.setPrevious(null); 157 size++; 158 } 159 else { 160 Node<E> temp = new Node<E>(); 161 temp.setO(element); 162 curr = head; 163 for(int i=1; i<size; i++) { 164 curr = curr.getNext(); 165 } 166 curr.setNext(temp); 167 temp.setPrevious(curr); 168 size++; 169 } 170 } 171 172 @Override 173 public void printList() { 174 // TODO 自动生成的方法存根 175 if(size<1) System.out.println("没有存入任何元素!"); 176 else { 177 curr = head; 178 for(int i=1; i<=size; i++) { 179 System.out.println(curr.getO()); 180 curr = curr.getNext(); 181 } 182 } 183 } 184 185 @Override 186 public E getFirst() { 187 // TODO 自动生成的方法存根 188 if(size<1) { 189 System.out.println("没有存入任何元素!"); 190 return null; 191 } 192 else { 193 return head.getO(); 194 195 } 196 } 197 198 @Override 199 public E getLast() { 200 // TODO 自动生成的方法存根 201 if(size<1) { 202 System.out.println("没有存入任何元素!"); 203 return null; 204 } 205 else { 206 curr = head; 207 for(int i=1; i<size; i++) { 208 curr = curr.getNext(); 209 } 210 return curr.getO(); 211 212 } 213 } 214 215 public Node<E> getHead() { 216 return head; 217 } 218 219 public void setHead(Node<E> head) { 220 this.head = head; 221 } 222 223 public Node<E> getCurr() { 224 return curr; 225 } 226 227 public void setCurr(Node<E> curr) { 228 this.curr = curr; 229 } 230 231 public Node<E> getTail() { 232 return tail; 233 } 234 235 public void setTail(Node<E> tail) { 236 this.tail = tail; 237 } 238 239 public Node<E> getPrevious() { 240 return previous; 241 } 242 243 public void setPrevious(Node<E> previous) { 244 this.previous = previous; 245 } 246 247 public void setSize(int size) { 248 this.size = size; 249 } 250 251 252 } 253 interface DoubleLinkedListImpl<E> { 254 255 /** 256 257 * 判断链表是否为空 258 259 * @return 260 261 */ 262 263 public boolean isEmpty(); 264 265 266 267 /** 268 269 * 获取当前链表节点数量 270 271 * @return 节点数 272 273 */ 274 275 public int getSize(); 276 277 278 279 /** 280 281 * 获取链表中第index个位置的节点的data值 282 283 * @param index:节点在链表中的位置 284 285 * @return:返回该节点的data值 286 287 */ 288 289 public E getData(int index); 290 291 292 293 /** 294 295 * 删除链表最后一个节点 296 297 */ 298 299 public void remove(); 300 301 302 303 /** 304 305 *删除链表中第index位置的节点 306 307 * @param index:节点在链表中的位置 308 309 */ 310 311 public void remove(int index); 312 313 314 315 /** 316 317 * 在链表的第index个位置之前插入一个节点,值为theElement,index∈[1,size] 318 319 * @param index:插入节点在链表中的位置 320 321 * @param theElement:新插入节点的data值 322 323 */ 324 325 public void add(int index, E theElement); 326 327 328 329 /** 330 331 * 在链表尾插入节点,插入节点data值为element 332 333 * @param element 334 335 */ 336 337 public void add(E element); 338 339 340 341 /** 342 343 * 输出链表 344 345 */ 346 347 public void printList(); 348 349 350 351 /** 352 353 * 获取第一个节点的data值 354 355 * @return 356 357 */ 358 359 public E getFirst(); 360 361 362 363 /** 364 365 * 获取链表最后一个节点的data值 366 367 * @return 368 369 */ 370 371 public E getLast(); 372 373 } 374 class Node<E> { 375 376 private E o; 377 private Node<E> next; 378 private Node<E> previous; 379 380 public Node() { 381 super(); 382 // TODO 自动生成的构造函数存根 383 } 384 385 public Node(E o, Node<E> next, Node<E> previous) { 386 super(); 387 this.o = o; 388 this.next = next; 389 this.previous = previous; 390 } 391 392 393 public E getO() { 394 return o; 395 } 396 397 public void setO(E o) { 398 this.o = o; 399 } 400 401 public Node<E> getNext() { 402 return next; 403 } 404 405 public void setNext(Node<E> next) { 406 this.next = next; 407 } 408 409 public Node<E> getPrevious() { 410 return previous; 411 } 412 413 public void setPrevious(Node<E> previous) { 414 this.previous = previous; 415 } 416 417 418 419 } 420 interface E { 421 422 }
(1)设计与分析:类似于C语言中的链表功能,head的next指向下一个节点,双向链表是一个节点既能指向下一个也能指向前一个,采用ArrayList和泛型。
(2)踩坑心得:增加与删除都要对size进行加减,此外,添加和删除要注意范围,若输入的index不合法,要忽略掉,弄清楚删除和添加的index是非为该index,要不要减一。
(3)改进建议:删除或添加可以调用getE(int index)的方法,提高代码的复用性。
4.期中考试
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:长度值 ```其中,所有数值均保留两位小数,建议可用

import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自动生成的方法存根 Scanner in = new Scanner(System.in); String regex1 = "\\d{1,}(\\.\\d{1,})?\\s{0,}"; String regex2 = "[a-z&&[A-Z]]"; double [] num = new double [4]; String color=" "; for(int i=0; i<5; i++) { String str = in.next(); if(i<4) { if(str.matches(regex1)) { String s[] = str.split("\\s+"); if(Double.parseDouble(s[0])>200) outPut(); else num[i]=Double.parseDouble(s[0]); } else outPut(); } else { color = str; } } Point point1 = new Point(num[0],num[1]); Point point2 = new Point(num[2],num[3]); Line line = new Line(point1,point2,color); line.display(); } public static void outPut() { System.out.println("Wrong Format"); System.exit(0); } } class Point{ private double x; private double y; public Point() { super(); // TODO 自动生成的构造函数存根 } public Point(double x, double y) { super(); 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() { } } class Line{ private Point point1; private Point point2; private String color; public Line() { super(); // TODO 自动生成的构造函数存根 } public Line(Point point1, Point point2, String color) { super(); 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.println("The line's color is:"+color); System.out.println("The line's begin point's Coordinate is:"); System.out.println("("+String.format("%.2f",point1.getX())+","+String.format("%.2f",point1.getY())+")"); System.out.println("The line's end point's Coordinate is:"); System.out.println("("+String.format("%.2f",point2.getX())+","+String.format("%.2f",point2.getY())+")"); System.out.println("The line's length is:"+String.format("%.2f",getDistance() )); } }
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)方法。
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自动生成的方法存根 Scanner in = new Scanner(System.in); String regex1 = "\\d{1,}(\\.\\d{1,})?\\s{0,}"; String regex2 = "[a-z&&[A-Z]]"; double [] num = new double [4]; String color=" "; for(int i=0; i<5; i++) { String str = in.next(); if(i<4) { if(str.matches(regex1)) { String s[] = str.split("\\s+"); if(Double.parseDouble(s[0])>200) outPut(); else num[i]=Double.parseDouble(s[0]); } else outPut(); } else { color = str; } } Element element = new Element(); Point p1 = new Point(num[0],num[1]); Point p2 = new Point(num[2],num[3]); Line line = new Line(p1,p2,color); Plane plane = new Plane(color); element = p1;//起点Point element.display(); element = p2;//终点Point element.display(); element = line;//线段 element.display(); element = plane;//面 element.display(); } public static void outPut() { System.out.println("Wrong Format"); System.exit(0); } } class Point extends Element{ private double x; private double y; public Point() { super(); // TODO 自动生成的构造函数存根 } public Point(double x, double y) { super(); 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",x)+","+String.format("%.2f",y)+")"); } } class Line extends Element{ private Point point1; private Point point2; private String color; public Line() { super(); // TODO 自动生成的构造函数存根 } public Line(Point point1, Point point2, String color) { super(); 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.println("The line's color is:"+color); System.out.println("The line's begin point's Coordinate is:"); System.out.println("("+String.format("%.2f",point1.getX())+","+String.format("%.2f",point1.getY())+")"); System.out.println("The line's end point's Coordinate is:"); System.out.println("("+String.format("%.2f",point2.getX())+","+String.format("%.2f",point2.getY())+")"); System.out.println("The line's length is:"+String.format("%.2f",getDistance() )); } } class Plane extends Element{ private String color; public Plane() { super(); // TODO 自动生成的构造函数存根 } public Plane(String color) { super(); this.color = 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); } } class Element{ public void display() { } }
3
在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。
- 在原有类设计的基础上,增加一个GeometryObject容器类,其属性为
ArrayList<Element>类型的对象(若不了解泛型,可以不使用<Element>) - 增加该类的
add()方法及remove(int index)方法,其功能分别为向容器中增加对象及删除第index - 1(ArrayList中index>=0)个对象 - 在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下:
- 1:向容器中增加Point对象
- 2:向容器中增加Line对象
- 3:向容器中增加Plane对象
- 4:删除容器中第index - 1个数据,若index数据非法,则无视此操作
- 0:输入结束
choice = input.nextInt(); while(choice != 0) { switch(choice) { case 1://insert Point object into list ... break; case 2://insert Line object into list ... break; case 3://insert Plane object into list ... break; case 4://delete index - 1 object from list int index = input.nextInt(); ... } choice = input.nextInt(); }输入结束后,按容器中的对象顺序分别调用每个对象的display()方法进行输出。
类图如下所示:

import java.util.ArrayList; import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自动生成的方法存根 Scanner in = new Scanner(System.in); String regex1 = "\\d{1,}(\\.\\d{1,})?\\s{0,}"; String regex2 = "[a-z&&[A-Z]]"; double [] num = new double [4]; String color=" "; GeometryObject gO = new GeometryObject(); int choice = in.nextInt(); while(choice != 0) { switch(choice) { case 1: for(int i=0; i<2; i++) { String str = in.next(); if(str.matches(regex1)) { String s[] = str.split("\\s+"); if(Double.parseDouble(s[0])>200) outPut(); else num[i]=Double.parseDouble(s[0]); } else outPut(); } Point p1 = new Point(num[0],num[1]); gO.add(p1); break; case 2: for(int i=0; i<5; i++) { String str = in.next(); if(i<4) { if(str.matches(regex1)) { String s[] = str.split("\\s+"); if(Double.parseDouble(s[0])>200) outPut(); else num[i]=Double.parseDouble(s[0]); } else outPut(); } else { color = str; } } Point p = new Point(num[0],num[1]); Point p2 = new Point(num[2],num[3]); Line line = new Line(p,p2,color); gO.add(line); break; case 3: color = in.next(); Plane plane = new Plane(color); gO.add(plane); break; case 4: int index = in.nextInt(); gO.remove(index); break; } choice = in.nextInt(); } for(Element list:gO.getList()) { list.display(); } } public static void outPut() { System.out.println("Wrong Format"); System.exit(0); } } class Point extends Element{ private double x; private double y; public Point() { super(); // TODO 自动生成的构造函数存根 } public Point(double x, double y) { super(); 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",x)+","+String.format("%.2f",y)+")"); } } class Line extends Element{ private Point point1; private Point point2; private String color; public Line() { super(); // TODO 自动生成的构造函数存根 } public Line(Point point1, Point point2, String color) { super(); 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.println("The line's color is:"+color); System.out.println("The line's begin point's Coordinate is:"); System.out.println("("+String.format("%.2f",point1.getX())+","+String.format("%.2f",point1.getY())+")"); System.out.println("The line's end point's Coordinate is:"); System.out.println("("+String.format("%.2f",point2.getX())+","+String.format("%.2f",point2.getY())+")"); System.out.println("The line's length is:"+String.format("%.2f",getDistance() )); } } class Plane extends Element{ private String color; public Plane() { super(); // TODO 自动生成的构造函数存根 } public Plane(String color) { super(); this.color = 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); } } class Element{ public void display() { } } class GeometryObject{ private ArrayList<Element> list = new ArrayList<>(); public void add(Element element) { list.add(element); } public void remove (int index) { if(index<=list.size()&&index>0) { list.remove(index-1); } } public ArrayList<Element> getList() { return list; } }
(1)设计与分析:1-3题是连续迭代,按照类图设计创建类、方法、属性,以及继承。题1:可以正则来判断格式,然后读取数据,传入point类,然后将point传传入Line类中;题2:添加一个类Palne将color传入,创建一个抽象类,抽象类作为父类;题3:创建了一个容器类,抽象类作为父类,方便使用容器类来存储,以此实现添加或删除对象的操作。
(2)踩坑心得:首先要看清楚类图,了解类与类之间的关系,构建起大体的框架,要按照类图设计,变量和方法不能随意更改,以及私有、公开要看清楚,此外,题2中的继承,Element为父类,point,plane,line为子类,题3中删除操作是删除容器中第index - 1个数据。
- (三)总结
本阶段(7-10周)学习了继承与多态、集合(Set)、数组(ArrayList)、正则表达式、以及图(Map)、流类(Stream)的相关知识,掌握了基本的用法,课堂上老师让我们自学了集合、图、流类的其他方法,对于这一方面,我仍需进一步学习和研究,因为这几块的知识内容较多,想要更好的掌握需要就一步的学习。
( 继承就是保持已有类的特性而构造新类的过程。继承后,子类能够利用父类中定义的变量和方法,就像它们属于子类本身一样。单继承:在类层次中,子类只继承一个父类的数据结构和方法,一个类只有一个父类。多继承:在类层次中,子类继承了多个父类的数据结构和方法,一个类允许有多个继承。多态体现为父类引用变量可以指向子类对象。Set:是一个内部自动有序且不含重复元素的容器。)
建议:课堂上可以多让我们动手实践,不仅仅是学习理论知识,还要去实践,对知识的进一步巩固、加深理解。多练习一下,及时发现自己的问题并及时改正。

浙公网安备 33010602011771号