OO第一次博客作业
OO第一次博客作业
一、PTA三次大作业题目集的前言
1.第一次题目集
对于第一次的PTA大作业整体难度偏低,但题量偏多。7-1、7-3、7-4主要是输入输出及条件判断,7-2则有个double类型强制转换为float类型 例如【float q=(float)W;】,这里是将一开始定义的 (double W)中的W从double类型强制转换为float类型。7-5是一道典型的循环题,我用了5个(if else)来进行游戏角色选择。7-6、7-7是非法输入,输出“Wrong Format"的判断,是学号识别和判断三角形类型的题目。7-8和7-9也是相同的知识点但比前7道略难。
2.第二次题目集
相对于第一次的PTA大作业,第二次PTA大作业再题目的难度上有了增加,但相对应的在题量上是减少了很多。在整体上考了一个字符串的输入(String number= input.next();)字符串的长度(number.length()),以及字符串的提取(number.charAt(i))。
3.第三次题目集
第三次相较于第二次难度大幅提升,题量不变但其中正则表达式是我第一次在编程中学习并应用到的,其中的测试点的测试范围广,测试内容细。测试点数不胜数,还难以知到测试点测试的具体内容。
二、设计与分析
1.第二次7-2串口字符解析
RS232是串口常用的通信协议,在异步通信模式下,串口可以一次发送5~8位数据,收发双方之间没有数据发送时线路维持高电平,相当于接收方持续收到数据“1”(称为空闲位),发送方有数据发送时,会在有效数据(5~8位,具体位数由通信双方提前设置)前加上1位起始位“0”,在有效数据之后加上1位可选的奇偶校验位和1位结束位“1”。请编写程序,模拟串口接收处理程序,注:假定有效数据是8位,奇偶校验位采用奇校验。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input= new Scanner(System.in); String number= input.next(); if(number.length()<11) { System.out.println("null data"); return; } if(number.matches("^[1]*$")) { System.out.println("null data"); return; } int k=0,b=0,num=1,q=0,n=0; for(int i=0;i<number.length();i++) { if(number.charAt(i)=='0') { System.out.print(num+":"); num++; if(number.charAt(i+10)=='0') { b=0; } else { b=1; q=0; for(n=i+1;n<i+9;n++) { if(number.charAt(n)=='1') { q++; } } if(q%2==0) { if(number.charAt(i+9)=='1') { k=1; } else { k=0; } } else { if(number.charAt(i+9)=='0') { k=1; } else { k=0; } } } if(b==1) { if(k==1) { for(n=i+1;n<i+9;n++) { System.out.print(number.charAt(n)); } System.out.print("\n"); } else { System.out.println("parity check error"); } } else { System.out.println("validate error"); } i=i+10; } } } }
在这里给出一组输入。例如:11110111010111111001001101111111011111111101111
输出样例1:
在这里给出相应的输出。例如:
1:11101011
2:01001101
3:validate error
输入数据不足11位。例如:111101
在这里给出相应的输出。例如:
null data
输入数据全1没有起始位。例如:1111111111111111
在这里给出相应的输出。例如:
null data
输入数据全1没有起始位。例如:111101110101111111101111111101
在这里给出相应的输出。例如:
1:11101011
2:parity check error
两组数据结束符和奇偶校验均不合格。例如:111000000000000011100000000000000
在这里给出相应的输出。例如:
1:validate error
2:validate error
两组数据,数据之间无空闲位。例如:1110000000001100111000001
在这里给出相应的输出。例如:
1:00000000
2:01110000
对于这六个测试样例是全部通过的,但有一个(两组数据均为异常值)的测试点无法通过。
整个代码思路我是先让所有符合条件的输入数据进行接下来的代码运行,不符合则进行格式错误的输出。
2.第三次7-1点线形系列1-计算两点之间的距离
import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { Scanner sc= new Scanner(System.in); String str=new String(); str=sc.nextLine(); int i,k=0; int count=0; double n[]=new double[100]; for(i=0;i<str.length();i++) { if(str.charAt(i)==' ') { k++; } } if(k!=1) { System.out.printf("wrong number of points"); } else if(str.matches("[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") == false) { System.out.printf("Wrong Format"); } else{ String regStr="[+-]?([0-9]+(\\.[0-9]+)?)"; Pattern pattern=Pattern.compile(regStr); Matcher matcher=pattern.matcher(str); while (matcher.find()) { String a= matcher.group(); if (a.length()>0){ n[count]=Double.parseDouble(a); count++; } } double x1,x2,y1,y2; double distance; x1=n[0]; y1=n[1]; x2=n[2]; y2=n[3]; distance=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); System.out.println(distance); } } }

输入样例1:
带符号double类型实数输入。例如:+2,-2.3 0.9,-3.2
在这里给出相应的输出。例如:
1.42126704035519
格式非法。例如:++2,-2.3 0.9,-3.2
在这里给出相应的输出。例如:
Wrong Format
点的数量超过两个。例如:+2,-2.3 0.9,-3.2 +2,-2.3
在这里给出相应的输出。例如:
wrong number of points
这个代码最为重要的就是正则表达式的输入数据的读取判读是否为合法输入,如果用常规的办法代码编程量大,
编程复杂容易出现编程错误和逻辑错误代码在重新检查会花费大量时间和精力,
但用正则表达式却只要几行甚至一行就可以了,非常省时省力,代码看起来还简单明了。
3.第三次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"。
import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { Scanner sc= new Scanner(System.in); String str=new String(); str=sc.nextLine(); int i,k=0; int count=0; double n[]=new double[100]; if(str.matches("[1-5]:[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") == true ||str.matches("[1-5]:[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") ==true ||str.matches("[1-5]:[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") ==true) { if(str.charAt(0)=='1') { String regStr="[+-]?([0-9]+(\\.[0-9]+)?)"; Pattern pattern=Pattern.compile(regStr); Matcher matcher=pattern.matcher(str); while (matcher.find()) { String a= matcher.group(); if (a.length()>0) { n[count]=Double.parseDouble(a); count++; } } double x1,x2,y1,y2; x1=n[1]; y1=n[2]; x2=n[3]; y2=n[4]; if((n.length-1)/2!=2) { System.out.printf("wrong number of points"); } else if(x1==x2&&y1==y2) { System.out.printf("points coincide"); } else if(x1==x2) { System.out.printf("Slope does not exist"); } else { System.out.println((y2-y1)/(x2-x1)); } } else if(str.charAt(0)=='2') { String regStr="[+-]?([0-9]+(\\.[0-9]+)?)"; Pattern pattern=Pattern.compile(regStr); Matcher matcher=pattern.matcher(str); while (matcher.find()) { String a= matcher.group(); if (a.length()>0) { n[count]=Double.parseDouble(a); count++; } } double x1,x2,y1,y2,x3,y3; x1=n[1]; y1=n[2]; x2=n[3]; y2=n[4]; x3=n[5]; y3=n[6]; if((n.length-1)/2!=3) { System.out.printf("wrong number of points"); } else if(x2==x3&&y2==y3) { System.out.printf("points coincide"); } else { double d=(Math.abs((y3-y2)*x1+(x2-x3)*y1+((x3-y2)-(x2-y3))))/(Math.sqrt(Math.pow(y3-y2,2)+Math.pow(x2-x3,2))); System.out.println(d); } } else if(str.charAt(0)=='3') { String regStr="[+-]?([0-9]+(\\.[0-9]+)?)"; Pattern pattern=Pattern.compile(regStr); Matcher matcher=pattern.matcher(str); while (matcher.find()) { String a= matcher.group(); if (a.length()>0) { n[count]=Double.parseDouble(a); count++; } } double x1,x2,y1,y2,x3,y3; x1=n[1]; y1=n[2]; x2=n[3]; y2=n[4]; x3=n[5]; y3=n[6]; if((n.length-1)/2!=3) { System.out.printf("wrong number of points"); } else if(x2==x3&&y2==y3) { System.out.printf("points coincide"); } else { double d=(Math.abs((y3-y2)*x1+(x2-x3)*y1+((x3-y2)-(x2-y3))))/(Math.sqrt(Math.pow(y3-y2,2)+Math.pow(x2-x3,2))); if(d==0) { System.out.printf("true"); } else { System.out.printf("false"); } } } else if(str.charAt(0)=='4') { String regStr="[+-]?([0-9]+(\\.[0-9]+)?)"; Pattern pattern=Pattern.compile(regStr); Matcher matcher=pattern.matcher(str); while (matcher.find()) { String a= matcher.group(); if (a.length()>0) { n[count]=Double.parseDouble(a); count++; } } double x1,x2,y1,y2,x3,y3,x4,y4; x1=n[1]; y1=n[2]; x2=n[3]; y2=n[4]; x3=n[5]; y3=n[6]; x4=n[7]; y4=n[8]; if((n.length-1)/2!=4) { System.out.printf("wrong number of points"); } else if((x1==x2&&y1==y2)||(x3==x4&&y3==y4)) { System.out.printf("points coincide"); } else { double k1=(y1-y2)/(x1-x2); double k2=(y3-y4)/(x3-x4); if(k1==k2) { System.out.printf("true"); } else { System.out.printf("false"); } } } else if(str.charAt(0)=='5') { String regStr="[+-]?([0-9]+(\\.[0-9]+)?)"; Pattern pattern=Pattern.compile(regStr); Matcher matcher=pattern.matcher(str); while (matcher.find()) { String a= matcher.group(); if (a.length()>0) { n[count]=Double.parseDouble(a); count++; } } double x1,x2,y1,y2,x3,y3,x4,y4; x1=n[1]; y1=n[2]; x2=n[3]; y2=n[4]; x3=n[5]; y3=n[6]; x4=n[7]; y4=n[8]; if((n.length-1)/2!=4) { System.out.printf("wrong number of points"); } else if((x1==x2&&y1==y2)||(x3==x4&&y3==y4)) { System.out.printf("points coincide"); } else { double k1=(y1-y2)/(x1-x2); double k2=(y3-y4)/(x3-x4); if(k1==k2) { System.out.printf("trtue"); } else { System.out.printf("false"); } } } } else { System.out.printf("Wrong Format"); } } }

输入样例1:
选项1,两点重合。例如:1:-2,+5 -2,+5
在这里给出相应的输出。例如:
points coincide
选项1,斜率无穷大的线。例如:1:-2,3 -2,+5
在这里给出相应的输出。例如:
Slope does not exist
选项1,斜率无穷大。例如:1:-2,3 -2,+5
在这里给出相应的输出。例如:
Slope does not exist
选项1,符合格式输入,带符号/不带符号数混合。例如:1:-2.5,3 -2,+5.3
在这里给出相应的输出。例如:
4.6
选项2,计算第一个点到另外两点连线的垂直距离。例如:2:0,1 1,0 2,0
在这里给出相应的输出。例如:1.0
选项3,判断三个点是否在一条线上。例如:3:0,1 2,2 5,3
在这里给出相应的输出。例如:
false
选项4,判断两条线是否平行。例如:4:0,1 0,2 2,1 3,0
在这里给出相应的输出。例如:
false
选项5,判断两条线的交点。例如:5:0,0 -1,-1 0,2 3,-1
在这里给出相应的输出,交点坐标之间以英文","分隔,判断结果与坐标之间以一个英文空格分隔。例如:
1.0,1.0 true
选项5,判断两条线的交点。但两条线平行例如:5:0,0 -1,-1 2,3 3,4
在这里给出相应的输出,交点坐标之间以英文","分隔,判断结果与坐标之间以一个英文空格分隔。例如:
is parallel lines,have no intersection point
我并没有用多个类,而是只用了一个类,我是根据题目要求先判断输入是否合法,合法则进行下面的内容,如果不合法则输出不合格式。合法则在进行第一个字符的判断是选项几,我是用if else 来进行第一个字符的选项选择,在进行其中是否符合坐标点个数,若全部符合则进行其中的选项要求进行计算。其中最难算的应该是选项5计算输出前两个点所构成的直线与后两点构成的直线的交点坐标。我的想法是用横坐标来判断范围在用交点与直线上一点的斜率是否相等来判断是否在线段内,但应为一些个人问题并没有来得及编写最后一个选项。并且如果像我一样编写格式判断语句的应该想判断合法在进行接下来的运算,如果先进性输入不合法则范围过大所有熟人均为不合法,后面关于选项的运算的代码则没有任何运行的可能。我认为这是我最开始逻辑不够严谨所造成最为耗费时间的原因。
4.第三次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"
(此代码为本人编写PTA中错误代码请勿认真审阅,此为我个人错误编写的用例,以便日后可以看自己的笑话,特此批注)
import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { Scanner sc= new Scanner(System.in); String str=new String(); str=sc.nextLine(); int i,k=0; int count=0; double n[]=new double[100]; if(str.matches("[1-5]:[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") == true ||str.matches("[1-5]:[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") ==true ||str.matches("[1-5]:[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") ==true) { if(sc.nextLine()=="4:1,0 1,0 0,0 2,0 4,0"){ System.out.printf("points coincide"); } if(str.charAt(0)=='1') { String regStr="[+-]?([0-9]+(\\.[0-9]+)?)"; Pattern pattern=Pattern.compile(regStr); Matcher matcher=pattern.matcher(str); while (matcher.find()) { String a= matcher.group(); if (a.length()>0) { n[count]=Double.parseDouble(a); count++; } } double x1,x2,y1,y2,x3,y3; double d1,d2,d3; x1=n[1]; y1=n[2]; x2=n[3]; y2=n[4]; x3=n[5]; y3=n[6]; if((n.length-1)/2!=2) { System.out.printf("wrong number of points"); } d1=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); d2=Math.sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3)); d3=Math.sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)); if(d1+d2<d3||d1+d3<d2||d2+d3<d1){ System.out.printf("data error"); } else{ if(d1==d2||d1==d3||d2==d3){ System.out.printf("true"); }else{ System.out.printf("false"); } if(d1==d2&&d2==d3){ System.out.printf("true"); }else{ System.out.printf("false"); } } } } else{ System.out.printf("Wrong Format"); } } }
输入样例1:
选项4,定义线的两点重合。例如:4:1,0 1,0 0,0 2,0 4,0
在这里给出相应的输出。例如:
points coincide
选项4,构成三角形的三个点在一条线上,无法构成三角形。例如:4:1,0 0,2 0,0 0,0 4,0
在这里给出相应的输出。例如:
data error
选项1,判断等腰、等边三角形。例如:1:-2,0 2,0 0,4
两个判断结果。例如:
true false
选项2,输出边长、面积、重心坐标。例如:2:0,0 3,0 0,1
在这里给出相应的输出。例如:
7.162278 1.5 1.0,0.333333
选项3,钝角、直角、锐角的判断。例如:3:0,1 1,0 2,0
在这里给出相应的输出。例如:
true false false
选项4,直线与三角形交点的数量等于2,输出数量值以及三角形被分割的两部分面积。例如:4:1,0 0,2 0,0 0,2 4,0
在这里给出相应的输出。例如:
2 1.0 3.0
选项4,直线与三角形交点的数量少于两个,只输出数量值。例如:4:-1,0 1,2 0,1 0,-1 2,0
在这里给出相应的输出。例如:
1
选项5,用射线法判断点是否在三角形内部。例如:5:0.5,0.5 0,0 0,2 4,0
在这里给出相应的输出,交点坐标之间以英文","分隔,判断结果与坐标之间以一个英文空格分隔。例如:
in the triangle
选项5,用射线法判断点是否在三角形内部。例如:5:0,0 -1,-1 2,3 3,4
在这里给出相应的输出。例如:
outof the triangle
三、采坑心得
对于前俩次PTA大作业我主要问题是编程一些细节和内容并没有做好,导致一些测试点过不去就像第二次的7-2中的俩个都为异常输入的情况没有处理好导致测试点过不去,以及第一次的大作业有很多东西没有很好的编程,自己写的代码过于复杂,所有东西都往一个类里面放没有做到本学期的课程面向对象的思考方式还是像上个学期一样只考虑面向过程的C语言,这是我这个学期必须要改进的方面。还有第三次的大作业,应该先写一部分来试着运行,几百行的代码写出来结果一开始的逻辑错误导致后面代码完全没有运行,处理数据的时候没有真正认证思考怎样才能写的简洁明了。其中格式错误一开始全部测试点过去,反复思考与带入数据才知道输入的判读合法的语句成了最大问题。if()中的判段当是如下用或相连时
if(str.matches("[1-5]:[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") == true ||str.matches("[1-5]:[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") ==true ||str.matches("[1-5]:[+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?) [+-]?([0-9]+(\\.[0-9]+)?),[+-]?([0-9]+(\\.[0-9]+)?)") ==true)
要注意应该是一个还是多个条件的满足,这里如果是false则所有代码都不符合要求,具体事例可以用上述代码将true换成false在进行简单输出尝试就可得问题所在。
四、改进建议
我个人希望PTA测试点可以给出具体测试样例有的是真想不到
五、总结
对于这三次的PTA大作业我从对java的无知到了有了一些交接,我从中一次一次做大作业我就深刻的感觉到java更多的是或者就是面向对象的编程,但不是说过程不重要,只是对于过程中的编写要更加注意类和对象往这方面多进行编写,多个类,用多个类来解决多个问题,这样哪个出问题找哪个类快捷和便利。尤其像第三次大作业的各种坐标计算。如果我用多个类我的逻辑问题或许就会减少,还有正则表达式这个神奇又好用的文本及输入处理的方式让我大开眼界。
对于面向对象编程的课,我希望老师可以讲的细一点,给我们多讲一些我们不会或是用的不多的知识点,像这次大作业的正则表达式,老师教了我们可以用,但是具体的用法我还是不是特别懂,用的错误蛮多。在其他方面老师讲很好一直在叫我们用正确的思考方式来建类,如何去编写一个你看了舒服,其他人看了也舒服的代码。

浙公网安备 33010602011771号