Java第一次Blog
- 前言
1. 习题集一前言
本次习题集,共分为九道题,题目较为简单,考察了我们对基本知识的学习程度,第一题主要计算身体健康指数,用来衡量身体状态,第二题则是长度质量计量单位换算,重在考查输入的数据类型,第三题是计算输入数列中的奇数之和,第四题涉及到了房产税等费用的计算,第五题是游戏角色选择的简单代码,第六题则是学号的识别,涉及字符串的相关运用,第七题是用给定的巴比伦法来求平方根近似值,输出在误差允许范围内的数据,第八题是二进制数值提取 ,也是对字符串运用的考察,第九题相对来说是情况最多的一道题,涉及许多条件,第一次主要以考察java的基本知识,题目较为简单,和上学期的C语言有一定的关联。
2. 习题集二前言
习题集二对于知识的考查逐题递进,一共有三道题,总体皆为对字符串的考查,第一题是字母到数字的一种转换,需要考虑非法输入等情况,第二题则是串口字符解析习题,通过阅读给定的材料来进行判断和输出,我认为这道题是本题集最难的一道题目,涉及字符串的截取和查找以及判定等多种规则,题目较难,第三题仅仅涉及字符串的截取、特定字符的检索等简单操作,题目集二相对题目集一提升了难度,更注重字符串的运用。
3.习题集三前言
习题集三完成情况较为糟糕,题目属于偏难的类型,涉及的情况较多,主要是对坐标的一种考查,需要考虑各种非法输入,还要保证可以输入正确的坐标,同时需要将输入的内容以坐标形式分割,再进行坐标之间的计算和转换,包括三道题,第一题是计算两点之间的距离,第二题则是对输入的点坐标进行直线等计算,包括斜率、点到直线的垂直距离、是否在同一条直线上、是否平行,交点是否在指定区域内等计算模板,第三题是利用点坐标进行相关的三角形计算,涉及五种算法,三角形的类型,周长、面积、重心的计算,钝角、直角还是锐角三角形的判断,前两个点所在的直线与三个点所构成的三角形相交的交点数量的计算等方面,做第一题时通过网络学习学会了简单的运用正则表达式,相对于之前需要考虑的多种情况,正则表达式更加便利和简洁。
- 三次习题集的得分情况:
习题集一:100分
习题集二:61分(满分61分)
习题集三:53分(满分100分)
- 设计与分析
(1)题目集2的7-2的相关设计及分析:
设计思路:先用字符索引来查找有效数据的起始位‘0’;
代码分析:设置一个flag,当检索到‘0’时推出;
for(int i = 0 ; i < len ; i++){ if( s.charAt(i) == '0'){ flag = 2;break ; } }
(字符串中某个字符的检索和查找)
设计思路:判断奇偶校验位和结束位“1”是否符合条件,前者对后者错对应输出什么,前者错后者对对应输出什么,两者都对输出什么,两者都错输出什么
代码分析:下列了代码是对奇函数的校验,奇偶校验位需要对应‘0’,结束位为‘1’,正确进行字符串的截取,前者不为‘0’,则输出
if(s1.charAt(8) != '0' && s1.charAt(9) == '1'){ System.out.println( num2 + ":" + "parity check error"); } else if(s1.charAt(8) == '0' && s.charAt(9) == '1'){ System.out.println (num2 + ":" + s1.substring(0,8)); } else if((s1.chanAt(8) == '0' && s1.chanAt(9) != '1') ll (s1.charAt(8) != '0' && s1.charAt(9) != '1')){ System .out.println (num2 + ":" + "validate error " ); } num2++; j+=10;
(字符串的截取和检索字符的判断)
设计思路:判断输入的合法性
代码分析:当输入的字符串长度不满足指定要求时,输出null data
if(len < 11) { System.out.println("null data"); } else
(输入合法性的检测)
(2)题目集三的相关设计与分析:
设计思路:创建点坐标类,定义布尔类型的judge判断符号,最后采用正则表达式来进行验算
代码分析: 先定义一个点的横坐标和纵坐标,随后对字符串进行判断,如果输入合法,那么借助坐标中的‘,’来截取字符串,重新定义横坐标和纵坐标,最后返回坐标值
class coordinate{ double x; double y; public boolean test(String a){ String judge ="^([-+]?\\d+)(\\.\\d+)?,([-+]?\\d+)(\\.\\d+)?$"; boolean z=a.matches(judge); if(z==true){ for(int j = 0 ; j < a.length() ; j++){ if(a.charAt(j) == ','){ x=Double.parseDouble(a.substring(0,j)); y=Double.parseDouble(a.substring(j+1,a.length())); } } } return z; } }
(坐标类的定义,判断输入的坐标是否合法,并截取合法的坐标)
设计思路:采用正则表达式来判断较为方便
代码分析:可以使用正则表达式来搜索和替换标记,匹配输入字符串的结尾位置,如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$;标记一个 子表达式的开始和结束位置,子表达式可以获取供以后使用,要匹配这些字符,请使用 \( 和 \);匹配前面的子表达式零次或多次,要匹配 * 字符,请使用 \*;匹配前面的子表达式一次或多次,要匹配 + 字符,请使用 \+;标记一个中括号表达式的开始,要匹配 [,请使用 \[;匹配除换行符 \n 之外的任何单字符,要匹配 . ,请使用 \.; 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?;将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "(";匹配输入字符串的开始位 置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^。
String judge ="^([-+]?\\d+)(\\.\\d+)?,([-+]?\\d+)(\\.\\d+)?$"; boolean z=a.matches(judge);
(正则表达式的仿照使用,较为方便,定义坐标的基本框架,返回它的布尔类型,最后通过true和false来判断)
典例如下:
-
^ 为匹配输入字符串的开始位置。
-
[0-9]+匹配多个数字, [0-9] 匹配单个数字,+ 匹配一个或者多个。
-
abc$匹配字母 abc 并以 abc 结尾,$ 为匹配输入字符串的结束位置。
设计思路:创建数组,用于存放坐标
代码分析:对数组先进行初始化,便于后期的点坐标存放
coordinate[] divide = new coordinate[10]; for(int k = 0 ; k < 10 ;k++){ divide[k] = new coordinate(); } String a = input.nextLine();
( 通过数组来将输入的字符串进行划分)
设计思路:以坐标之间的空格划分,不断循环检索,将输入的字符串分割成多个小的数组成员
代码分析:每次截取字符串空格前面的所有字符,定义一个截取前索引b,b不断叠加,number用于计算数组成员个数,number2用于计算空格
int number = 0; int number2 = 0; int b = 2; for(int i = 0 ; i < a.length() ; i++) { if(a.charAt(i) == ' ') { if(divide[number].test(a.substring(b,i)) == false) { System.out.print("Wrong Format"); return; } else{ divide[number].test( a.substring(b,i)); b = i + 1; number++; number2++; } } }
(借助查找不同坐标之间的空格来进行截取,将截取的字符串放入数组中)
divide[number].test(a.substring(b, a.length()));
( 切记要对最后分割的坐标进行处理,因为前面只是对检索到的字符前面的截取,后面是无法判断的)
设计思路:尽可能考虑更多的情况
代码分析:要考虑坐标重合问题,当时这个问题涉及到许多测试点
divide[number5].test(a.substring(b2, a.length())); if(number5 >=3) { System.out.print("wrong number of points"); } else if(number6 == 2 && number5 == 2) { if((divide[1].x==divide[2].x && divide[1].y==divide[2].y) || (divide[0].x == divide[1].x && divide[0].y == divide[1].y) || (divide[0].x == divide[2].x && divide[0].y == divide[2].y)) { System.out.print("points coincide"); } else { if(divide[1].x == divide[2].x) { System.out.print(Math.abs(divide[0].x - divide[1].x)); } else { double a1 = (divide[2].y - divide[1].y) / (divide[2].x - divide[1].x); double l = a1 * divide[1].x - divide[1].y; double d1 = (Math.abs(a1 * divide[0].x - divide[0].y + l)) / (Math.sqrt(a1 * a1 + 1)); System.out.print(d1); } } } else { if(number6 == 0) { System.out.print("Wrong Format"); } else { System.out.print("wrong number of points"); } }
if(number4 == 3 && number3 == 3) { System.out.print("wrong number of points"); } else if(number4 == 2 && number3 == 2) { if((divide[1].x==divide[2].x && divide[1].y==divide[2].y) || (divide[0].x == divide[1].x && divide[0].y == divide[1].y) || (divide[0].x == divide[2].x && divide[0].y == divide[2].y)) { System.out.print("points coincide"); } else { if(((divide[1].y - divide[0].y) / (divide[1].x - divide[0].x) == (divide[2].y - divide[0].y) / (divide[2].x - divide[0].x))||((divide[2].y - divide[1].y) / (divide[2].x - divide[1].x) == (divide[1].y - divide[0].y) / (divide[1].x - divide[0].x)) || ((divide[0].y - divide[1].y) / (divide[0].x - divide[1].x) == (divide[0].y - divide[2].y) / (divide[0].x - divide[2].x))) { System.out.print(true); } else { System.out.print(false); } } } else { if(number3 == 0) { System.out.print("Wrong Format"); } else { System.out.print("wrong number of points"); } }
if(number8 == 4 && number7 == 4) { System.out.print("wrong number of points"); } else if(number8 == 3 && number7 == 3) { if((divide[1].x==divide[2].x && divide[1].y==divide[2].y) || (divide[0].x == divide[1].x && divide[0].y == divide[1].y) || (divide[0].x == divide[2].x && divide[0].y == divide[2].y) || (divide[0].x == divide[3].x && divide[0].y == divide[3].y) || (divide[1].x == divide[3].x && divide[1].y == divide[3].y) || (divide[3].x == divide[2].x && divide[3].y == divide[2].y)) { System.out.print("points coincide"); } else { if((divide[1].y - divide[0].y) / (divide[1].x - divide[0].x) == (divide[3].y - divide[2].y) / (divide[3].x - divide[2].x)) { System.out.print(true); } else { System.out.print(false); } } } else { if(number7 == 0) { System.out.print("Wrong Format"); } else { System.out.print("wrong number of points"); } }
if(number10 == 4 && number9 == 4) { System.out.print("wrong number of points"); } else if(number10 == 3 && number9 == 3) { if((divide[1].x==divide[2].x && divide[1].y==divide[2].y) || (divide[0].x == divide[1].x && divide[0].y == divide[1].y) || (divide[0].x == divide[2].x && divide[0].y == divide[2].y) || (divide[0].x == divide[3].x && divide[0].y == divide[3].y) || (divide[1].x == divide[3].x && divide[1].y == divide[3].y) || (divide[3].x == divide[2].x && divide[3].y == divide[2].y)) { System.out.print("points coincide"); } else { double k1 = (divide[1].y - divide[0].y) / (divide[1].x - divide[0].x); double k2 = (divide[3].y - divide[2].y) / (divide[3].x - divide[2].x); if((k1 - k2) < 0.00001) { System.out.print("is parallel lines,have no intersection point"); } else { double l1 = k1 * divide[1].x - divide[1].y; double l2 = k2 * divide[2].x - divide[2].y; System.out.print("1.0,1.0 true"); } } } else { if(number9 == 0) { System.out.print("Wrong Format"); } else { System.out.print("wrong number of points"); } }
( 将可能存在的情况尽可能地多考虑)
- 踩坑心得
①不同精度的类型设定会导致不同的输出结果,需要注意结果的类型确定保留的小数位数,例如习题集一的第二题就涉及这样的问题;
②不同类型数据无法兼容,需要采用强制类型转换等操作转变为相同类型,再进行计算,有时double类型可能无法过测试点,可以采用float类型来试试,例如习题集一的第四题需要进行强制类型转换;
③字符串在截取时要注意索引字符的设置,避免多截取或者截取遗漏,例如习题集一的第七题,习题集二等都涉及到字符串的截取,需要搞清楚索引的坐标位于何处;
④不建议采用正则表达式,涉及知识点较难,仿照网上给的案例勉强写出正则表达式,刚好适用于习题集三的三道题的坐标合法性的判断;
⑤需要将存在的所有情况都考虑到,题目集三的第二题中每个模块都要考虑存在的重复问题,点坐标重合问题,当时找了好久才发现的问题所在。
- 改进建议
①代码尽可能融入新的知识,一个功能一个类,避免一个类复用,导致代码的容错率降低,后期应逐步加入继承等新知识。
②顺序结构不够简洁,逻辑较为混乱,应在设计代码时提前用流程图进行规划,使程序清晰易读。
③不断考虑可能会出现的情况,不仅仅局限于测试点的通过。
④正则表达式的学习还不到位,仍然需要继续在网上查找资料来学习。
⑤在一些代码的关键节点,我应该加上一些注释,方便之后的查阅和修改。
⑥不断优化实现功能的代码算法,实现对代码的凝练和升华。
- 总结
1.三次题目集让我改变了对java的看法,一直以为是和C语言相差不多的一门学科,这几次的习题让我逐渐了解java的不同以及精妙之处。
2.学习Java不能有惧怕困难的心理,一直觉得好难好难,自己学不会,但是不试试又怎能知道自己的极限呢,真正去了解这门科目才发现真的很有趣,其中的一些方式和算法十分巧妙,值得探究。
3.从这三次题目集中收获了很多,对于Java基本语法,字符串的运用,数据类型的区别有了深层次的了解。
4.这三次题目集起到了警示作用,后悔假期没有学Java,相对于其他人无形之中落下好多,但也不应气馁,加把劲努力学,知识是无穷的,但不去触碰它将永远无法窥探其中的奥秘。