期中考试及4、5题目集pta测试
前言
知识点:1.正则表达式
2.类设计、继承与多态、容器类
3.类与对象、字符串方法调用、边界值判断
4.接口、泛型、基本链表结构
题目关联性:均较强,难度逐步提升。
设计与分析
题目集4:
7-1 点线形系列1-计算两点之间的距离
输入连个点的坐标,计算两点之间的距离
输入格式:
4个double类型的实数,两个点的x,y坐标,依次是x1、y1、x2、y2,两个点的坐标之间以空格分隔,每个点的x,y坐标以英文“,”分隔。例如:0,0 1,1或0.1,-0.3 +3.5,15.6。
若输入格式非法,输出"Wrong Format"。
若输入格式合法但坐标点的数量超过两个,输出“wrong number of points”。
输出格式:
计算所得的两点之间的距离。例如:1.4142135623730951
输入样例:
整数输入。例如:
0,0 1,1
输出样例:
在这里给出相应的输出。例如:
1.4142135623730951
输入样例1:
带符号double类型实数输入。例如:
+2,-2.3 0.9,-3.2
输出样例1:
在这里给出相应的输出。例如:
1.42126704035519
输入样例2:
格式非法。例如:
++2,-2.3 0.9,-3.2
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
输入样例3:
点的数量超过两个。例如:
+2,-2.3 0.9,-3.2 +2,-2.3
输出样例3:
在这里给出相应的输出。例如:
wrong number of points
分析:
本题相对较为简单,考察分割字符串的方法,这里可以使用正则(比较好想但是实现好像比较困难),也可以使用常规方法,我使用的就是charAt(常规方法),但是确一直有几个测试点无法通过,我不知道测试点所以过不了,以下是我的代码。
代码:
public class Main{
public static void main(String []args){
Scanner scanner = new Scanner(System.in);
String oldStr = scanner.nextLine();
int k=0;
for(int z=0;z<oldStr.length();z++)
{
if(oldStr.charAt(z)==',')
k++;
}
String[] strs = oldStr.split(" ",k);//根据,切分字符串;切两份
String a=strs[0];
String b=strs[1];
String[] c = a.split(",",2);
String[] d = b.split(",",2);
String e=c[0];
String f=c[1];
String g=d[0];
String h=d[1];
double xy=0;
int x=0;
for(int i=0;i<e.length();i++){
if((e.charAt(i)>='0'&&e.charAt(i)<='9')||e.charAt(i)=='.')
break;
else
x++;
}
int y=0;
for(int l=0;l<f.length();l++){
if((f.charAt(l)>='0'&&f.charAt(l)<='9')||f.charAt(l)=='.')
break;
else
y++;
}
int z=0;
for(int m=0;m<g.length();m++){
if((g.charAt(m)>='0'&&g.charAt(m)<='9')||g.charAt(m)=='.')
break;
else
z++;
}
int u=0;
for(int v=0;v<h.length();v++){
if((h.charAt(v)>='0'&&h.charAt(v)<='9')||h.charAt(v)=='.')
break;
else
u++;
}
if(u>1||x>1||y>1||z>1){
System.out.println("Wrong Format");
}
else if(k!=2)
System.out.println("wrong number of points");
else if(e.contains(" ")||f.contains(" ")||g.contains(" ")||h.contains(" ")){
System.out.println("Wrong Format");
}
else{
double x1=Double.parseDouble(e);
double y1=Double.parseDouble(f);
double x2=Double.parseDouble(g);
double y2=Double.parseDouble(h);
xy = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
System.out.println(xy);
}
}
}
7-2 点线形系列2-线的计算:
用户输入一组选项和数据,进行与直线有关的计算。选项包括:
1:输入两点坐标,计算斜率,若线条垂直于X轴,输出"Slope does not exist"。
2:输入三个点坐标,输出第一个点与另外两点连线的垂直距离。
3:输入三个点坐标,判断三个点是否在一条线上,输出true或者false。
4:输入四个点坐标,判断前两个点所构成的直线与后两点构成的直线是否平行,输出true或者false.
5:输入四个点坐标,计算输出前两个点所构成的直线与后两点构成的直线的交点坐标,x、y坐标之间以英文分隔",",并输出交叉点是否在两条线段之内(不含四个端点)的判断结果(true/false),判断结果与坐标之间以一个英文空格分隔。若两条线平行,没有交叉点,则输出"is parallel lines,have no intersection point"。
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。
例如:1:0,0 1,1
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
不论哪个选项,如果格式、点数量都符合要求,但构成任一条线的两个点坐标重合,输出"points coincide",
输出格式:
见题目描述。
分析:
本题首先将输入的数据提取运用,并利用subString的方法进行数据提取,由于存在错误输入的问题,需对输入是可能的情况进行分析,如:1:0,0 1,1、1:0 0, 1 1,1……得到Wrong Format的结果,同时也因出现点输入数量不符的情况,需与错误输入区分后单独讨论,接下来是对前四个选项功能的实现最后一个选项相对复杂许多,首先需要考虑两直线平行的情况(注意斜率不存在),点重合的情况依旧需要考虑,对于判断交点的计算我是列方程得出通解,再利用Math类中的max和min方法得到极大和极小点,再判断是否在两条线段之内。
7-3 点线形系列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"
分析:三角形计算主要是对数学方法的考察,7-3正好可以利用7-2的输入,三角形任意两边之和大于第三边,周长公式,重心公式限制点和边,海伦公式解决三角形面积,三角形类型便使用余弦定理。但是实现和检验我仍然出现了问题,射影法也不能很好的解决验算问题。所以我在思考一种新思路,就是利用拆分法达成验算效果,将一个三角形切分成较为容易计算面积的图形。
期中考试
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)方法。
分析:此题考察的是看类图实现需求的能力(我没把类图复制下来现在看不到了QWQ)。
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();
分析:本题是通过多定义一个父类,通过让Line、Point和Plane类继承父类实现多态。
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()方法进行输出。
分析:本题是考察的仍然是通过类图书写容器,而容器类多态我都没有掌握,所以书写这两道题对我而言相当困难。
总结
踩坑心得:
最大的问题便是垃圾代码,很多时候写出来的很多代码可以精简很多或者通过另一种跟简单的方式来实现想法,这样相当不利,而且我的代码时常出现一些小的语法错误,小错误常犯对以后的工作来说也是相当不利的,审题不细也是我的问题之一,之前做题目集4时我拿到题目就开始写,第一遍甚至没有注意到点的输入到底如何为正确,“,”被我直接省去,提交之后我还在思考为啥答案错误,读懂需求的习惯没有养成。
反思:
在课余时间中留给java的时间太少,导致题目集到了截至日期才开始完成作业,这自然使得给自己留出的思考和实现时间被很大压缩,这样对整个整体思维都是不利的,我需要分配更多思考时间给它,用更大的精力来投入其中才行。Java的学习其实更让我看到了一些其他学科比如数学的短板。很多知识点的实现与运用都是要有足够多的数学知识(其他学科知识)来支撑的,也更让我深刻理解了学科与学科之间的紧密联系,而非大学之前那种散沙般的知识摄取。一个优秀的设计师同时也应该是一个知识储备丰富的学者,这也给我多学习一些其他学科相关内容的动力。

浙公网安备 33010602011771号