PTA前三周作业总结
-
前言(作业题目总结)
前三次作业都是对Java学习情况的一个检查。就个人而言,前两次作业考察的内容与之前学的C语言有相似之处,因此做起来可能没有特别大的难度。是加强Java基本语句熟练度的两次作业,虽然题目数量比第三次作业多,但还是比较轻松。第三次的作业确实是对我的一个很大的挑战。第三次作业主要是考察正则表达式的学习情况,虽然只有三题,但是花费了很多时间在学习正则表达式的恰当运用上。做第一题的时候甚至没有想到用正则表达式,导致花了很多时间。
-
设计与分析
- 第二次大作业 --- 串口字符解析
这次作业我觉得主要就是字符串的处理问题,合理运用Java工具类函数就能把串口字符按题目要求截取,然后单独判断输出结果。
类图:

因为只需要相应切割逐个判断,就没有过多的函数,一Main到底了。
附主功能代码
public class Main { public static void main(String[] args) { java.util.Scanner in = new java.util.Scanner(System.in); String a = in.nextLine(); int no = -1; int cnt = 1;//第几个输出 int cnt1= 0;//统计1的个数 no = a.indexOf('0'); if(no == -1||a.length()<11) System.out.println("null data"); else { while(no!=-1) { if(no+11>a.length()) {break;} else { char isch2;//判断位应该为啥 String b = a.substring(no,no+11); for(int i=1;i<9;i++) { char ch = b.charAt(i); if(ch == '1') cnt1 ++; } if(cnt1 %2 == 0) isch2 = '1'; else isch2 = '0'; cnt1=0; char ch1 = b.charAt(10);//结束 char ch2 = b.charAt(9);//判断位 if(ch1 !='1') {System.out.println(cnt + ":" + "validate error");cnt++;} else if(ch2 != isch2) {System.out.println(cnt + ":" + "parity check error");cnt++;} else { System.out.println(cnt + ":" + b.subSequence(1, 9)); cnt++; } no = a.indexOf('0', no+11); } } } } }
- 判断合法输入
- 向后取11位并判断1的个数,确定奇偶校验位数字。
分析图:

这个题就用Java的String类中的函数,遇到判定的数字就往后切割八位进行判断。记录1出现的次数作为奇偶校验位。
这道题我选择直接用切割出指定长度的字符串进行判断,使用indexof函数寻找下一个符合的字符串并使之成为子串。虽然代码不是特别长,但是如果能使用函数的方法分开功能,应该会更好一点。
- 第三次大作业 --- 点线形系列1-计算两点之间的距离
主要考察的是正则表达式的使用,但是我没了解过正则表达式,就没有使用,而是选择一板一眼的用if语句和for循环判断条件,浪费了很多时间,并且代码的质量也不够好,虽然能通过所有的测试点,但是可能对于更多的数据,还是存在些许bug。
类图:

这道题还是一Main到底(无效写题),代码利用率特别低,重复代码很多。
switch(don) { case 0:x1 = Double.parseDouble(b);don++;k+=b.length()+1; break; case 1:y1 = Double.parseDouble(b);don++;k+=b.length()+1; break; case 2:x2 = Double.parseDouble(b);don++;k+=b.length()+1; break; case 3:y2 = Double.parseDouble(b);don++;k+=b.length()+1; break; }
类似这种。
并且这种方法特别容易考虑不全,导致错判漏判,以后还是得加以改进,使用更加全面的方法解决问题。
分析图:

- 第三次大作业 --- 点线形系列2-线的计算
在经过第一题的折磨后,开始学习正则表达式的使用了。第一题还能用for和if语句强行判断下来,但是第二题开始,正则表达式的优势就完全显现出来了。首先就是输入格式的判断,正则表达式可以很直观的检测出输入的字符串是否符合规范,不符合规范的字符串可以直接输出错误提示并结束程序,相较于第一题的艰难寻找来说,省事了特别多。并且学习了正则表达式的相关内容,使用
import java.util.regex.Pattern; import java.util.regex.Matcher;
正则表达式中Pattern类和Matcher类,可以直接计算出输入点的数量,方便直接判断点数是否符合规范。
String b = new String("[+-]?\\d+(\\.\\d+)?\\,[+-]?\\d+(\\.\\d+)?"); Pattern pattern = Pattern.compile(b); Matcher mat = pattern.matcher(a); int cnt = 0; //点的个数 while(mat.find()){ cnt++;
在判断正确格式的同时,按点分割,计算输入的点数。
类图:

这题开始定义了一个点类,方便储存输入的点的坐标。
class Dian { double x,y; }
定义了一个点类
private static int geidian(String jian,int cnt) { cai = jian.split(",|\\s"); boolean istrue = true; for(int j=0;j<cai.length;j++) { if(cai[j].length()>1) if(cai[j].charAt(0)=='0'&&cai[j].charAt(1)!='.') {istrue = false;break;} } if(istrue) { for(int j=0,i=0;j<cai.length;j+=2,i++) { s[i] = new Dian(); s[i].x = Double.parseDouble(cai[j]); s[i].y = Double.parseDouble(cai[j+1]); } return 1; }
输入点的坐标并储存
并且改变了一Main到底的格式,将每个功能分成函数,提高了代码利用率,并且减少了代码重复,提高质量。
分析图:

还有待提高代码利用率
- 第三次大作业 --- 点线形系列3-三角形的计算
这道题是这三次作业中唯一一道没有完成的题目,这道题前半部分的内容与第二题大致一样,主要的难点就在选项四和选项五上。
4:输入五个点坐标,输出前两个点所在的直线与三个点所构成的三角形相交的交点数量,如果交点有两个,则按面积大小依次输出三角形被直线分割成两部分的面积。若直线与三角形一条线重合,输出"The point is on the edge of the triangle"
5:输入四个点坐标,输出第一个是否在后三个点所构成的三角形的内部(输出in the triangle/outof triangle)。
必须使用射线法,原理:由第一个点往任一方向做一射线,射线与三角形的边的交点(不含点本身)数量如果为1,则在三角形内部。如果交点有两个或0个,则在三角形之外。若点在三角形的某条边上,输出"on the triangle"
选项四因为函数没有泛用性,导致很多相似功能性函数得重写,没完成好。
类图:

- 判断合法输入
- 将输入的坐标存进点类
- 根据选项进入相应函数
分析图:

前三个选项和错误输入方面都已经尽力完善了,但是后面的代码还是有待提高。
-
踩坑心得
- 在第三次作业的第一题提交的时候,总是有几个测试点过不去,仔细检查才发现是输出“Wrong Format”的时候拼写错误导致答案错误,这种低级的错误属实不该犯!!
- 在第三次作业的第二题和第三题中,出现了大量计算,但是爆double了,出现了精度错误。
换成了差值小于1e-5解决了精度问题,通过了测试点。
- 第三次作业的第三题出现了保留位数的问题。
按照if语句判断的话,代码很复杂,看起来也很不舒服,后面了解到了Java的另一个工具类函数。
注意:输出的数据若小数点后超过6位,只保留小数点后6位,多余部分采用四舍五入规则进到最低位。小数点后若不足6位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333333,1.0按格式输出为1.0
利用函数的格式判断,import java.text.DecimalFormat;可以直接按照题目要求的格式输出,通过测试点。但是从代码重复来看,还有待提升,但是学到了新的知识还是很不错的。String m1 = new DecimalFormat("#0.0#####").format(zhou); String m2 = new DecimalFormat("#0.0#####").format(mian); String m3 = new DecimalFormat("#0.0#####").format(xn); String m4 = new DecimalFormat("#0.0#####").format(yn);
- 在第三次作业的第三题中,我写了一个储存交点的类,并且写了一个功能函数来找交点,
因为考虑不周全,所以导致这个又臭又长函数只能做一个是否有交点的判断,显得比较鸡肋。
private static int findjiao(Dian a, Dian b, Dian c, Dian d) { boolean inside = false; double a1 = a.y-b.y; double b1 = a.x-b.x; double c1 = a1*a.x+b1*a.y; double a2 = c.y-d.y; double b2 = c.x-d.x; double c2 = a2*c.x + b2*c.y; double xn = -(c2*b1-c1*b2)/(a1*b2-a2*b1); double yn = (c1*a2-c2*a1)/(a1*b2-a2*b1); if(xn>=Math.min(c.x, d.x)&&xn<=Math.max(c.x, d.x)) { inside = true; if(jia==0) { ss[0] = new Dian(); ss[0].x = xn; ss[0].y = yn; jia++; return 1; } else { if(xn!=ss[jia-1].x&&yn!=ss[jia-1].y) { ss[jia] = new Dian(); ss[jia].x = xn;s[jia].y = yn; jia++; return 1; } } } return -1; }
-
改进建议
- 首先在写代码前要有整体的构思,要明确要写多少个功能函数,并且要考虑到功能函数的泛用性,不能仅限于为某一段代码服务,要能够被整个代码利用,要具有通用性。
- 遇到精度问题的时候,用math函数解决问题,直接的数学判断容易出现差错。
- 输出注意格式,要仔细审题,不要犯马虎的错,拼错单词打错字母这种事,最好不要再犯。
-
总结
- 总的来看,这三次大作业我更加熟悉了Java的基本语句的使用,包括字符串判断,传参,定义类和对象,通过网上查询资料,询问周围同学(大佬),学到了很多Java的工具类函数,提高了代码的质量和效率,感谢我身边帮助我的人,谢谢谢谢。
- 这几次作业让我学习到了很多新的知识,但是我对这些函数都只是知道一点皮毛,看资料后依葫芦画瓢加入自己的代码中进行运用,并没有透彻了解,需要进一步深入,将知识融会贯通,真正掌握才是学到了。在网上查询资料的同时,我也发现了很多有趣而且功能强大的函数,以及一些提高算力的算法,虽然这几次作业可能并没有用上,但是这激发了我深入学习的兴趣,我觉得这是我三次作业以来最大的一个收获。

浙公网安备 33010602011771号