Blog1-前三次作业分析
新的学期开始到现在已经过去一个多月,新的学期学习了一门新的语言java,对于Java感觉和上学期学的C,还是有较大的区别,对于Java,更多的是思考如何对一个问题进行分类处理,相较于C从头写到尾的直接,Java更注重如何创建类之间的关系,并且让类之间的关系更加有序。当然新语言的学习还需努力,从之前的面向过程思维尽快转换成面向对象思维。话不多说,我们直接进入正题。
目前我们已经做了三次作业,这里总结一下:
一. 作业分析
第一次作业:
(1) 题量:共九题,题量中等
(2) 难度:难度较低,但是作业对于格式的把控非常严格,直到快交作业时才,测试出没过的测试点问题是出在变量的类型应该是float,而不能是double上!
(3) 主要考查了java的基础语法的使用
第二次作业:
(1) 题量:共三题,但题量较少,整体难度不大。
(2) 难度:难度较第一次稍稍提高,但格式判断较为容易
(3) 考查知识:主要考察java中自带的字符串类的使用,考察了关于字符串处理的各种功能。
第三次作业:
(1) 题量:共三题,整体来说题量不大(容易让人低估提的难度)
(2) 难度:与前两次作业比较,难度有所提升,三道题目之间相互关联,且格式判断难度增大
(3) 考查知识点:字符串的格式判断,三角形与直线之间的关系。
二. 题目设计与分析
第一次作业:
类图:

第一次作业主要是考查java的基础语法,例如,输入输出的语法格式,如何创建一个数组,以及使用switch-case的使用,java语法与C较为相像,其次此次题目比较简单,所以在解决题目的过程中,没有明确的对题目进行明确的分类。所以每个题目只有main类。这也是需要改进的地方。
第二次作业:
类图:

这次作业在难度上有所升级,但也让我快速意识到了java语言的便捷之处,比如java里自带String类等使用时可以直接调用十分方便。当然通过我的类图,可以看出,我还没有建立类的概念。这里以第二题为例。
上代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); String number = in.nextLine(); int flag = 0,count = 0; int ass = 0,cnt = 1; if(number.length()<11) { System.out.print("null data"); ass = 1; }else { for(int i = 0;i < number.length();i++) { if(number.charAt(i)=='0') { flag = 1; } } if(flag == 0) { System.out.print("null data"); ass = 1; } } if(ass == 0) { for(int i = 0;i<number.length();i++) { if(number.charAt(i) == '0'&&i+10<number.length()) { for(int j = i+1;j<=i+8;j++) { if(number.charAt(j) == '1') count++; } } if(number.charAt(i) == '0'&&i+10<number.length()&&number.charAt(i+9)=='1'&&number.charAt(i+10)=='1'&&count%2 == 0) { for(int j = i+1;j<=i+8;j++) { if(j == i+1) System.out.print(cnt+":"); System.out.print(number.charAt(j)); } System.out.println(); i = i+10; cnt++; count = 0; }else { if(number.charAt(i) == '0'&&i+10<number.length()&&number.charAt(i+9)=='0'&&number.charAt(i+10)=='1'&&count%2 == 1) { for(int j = i+1;j<=i+8;j++) { if(j == i+1) System.out.print(cnt+":"); System.out.print(number.charAt(j)); } System.out.println(); i = i+10; cnt++; count = 0; }else { if(number.charAt(i) == '0'&&i+10<number.length()&&number.charAt(i+10)!='1') { System.out.print(cnt+":"+"validate error"); System.out.println(); i = i+10; cnt++; count = 0; }else { if(number.charAt(i) == '0'&&i+10<number.length()&&number.charAt(i+10)=='1'&&count%2 != 0&&number.charAt(i+9)=='1') { System.out.print(cnt+":"+"parity check error"); System.out.println(); i = i+10; cnt++; count = 0; }else { if(number.charAt(i) == '0'&&i+10<number.length()&&number.charAt(i+10)=='1'&&count%2 == 0&&number.charAt(i+9)=='0') { System.out.print(cnt+":"+"parity check error"); System.out.println(); i = i+10; cnt++; count = 0; } } } } } } } }
通过代码可以看到,代码的前半部分用了很大的篇幅去判断格式是否正确,这对我也是一个难点。后面便是对读进来的字符串进行分析和提取。
其中使用了java中字符串类的一些功能:
比如:String.Length()可以直接返回字符串的长度
以及String.charAt(int index)可以返回字符串中index位置上的值。
代码中还大量使用了if判断和for循环,来对字符串遍历,对字符串中的每个元素进行判断。
第三次作业:
类图:

第三次作业开始尝试创建类,但是对将那些作为对象建类还没有较好的的把握,所以建立了一些类似于C语言函数的类(功力不够,还需学习)。
下面具体分析一下每一题:
第一题:让求两点间的距离,问题不是很难,但是输入数据的格式判断和每个坐标的提取分离确实是比题目本身更难的点。此题我一共写了两个类一个main类,一个计算类(大佬勿笑,此类分的很没有水平)
然后着重说一下我认为比较难得提取坐标,我将字符串转化成数组,并将其中的,号变成空格,再使用String.Split()
将字符串按空格分隔,将分隔后的每一部分放入数组中:
代码如下:
char[] str1 = str.toCharArray(); for(int i = 0;i<str.length();i++) { if(str1[i] == ',') { str1[i] = ' '; } } String str2 = new String(str1); String[] str3 = str2.split(" "); double[] du = new double[str3.length]; for(int i = 0;i < str3.length;i++) { double number = Double.parseDouble(str3[i]); du[i] = number; }
这道题目对于我的难点在于格式判断,考虑不全所有的错误输出格式,导致此题没有通过。
第二题:
第二题可以说是第一题的进阶版,此题主要是对线进行分析,计算线的斜率,两线是否平行,点到线的距离,以及两直线的交点。
当然线是由点组成的,所以第一题的部分代码可以为第二题做铺垫,此题我写了六个类,当然都是计算类,而不是应该创建的point 类和line 类。第二题,坐标的提取我使用了第一题的方法。
下面将注重说一下我创建的类:
第二题类图:

可以看到我只是按照题目要求的功能进行分类,并没有创建真正的具有意义的类。
然后再具体分析一下main里的代码:
switch ((int)du[0]) { case 1: if(du.length == 5) { One.jisuan(du[1], du[2], du[3], du[4]); }else { System.out.print("wrong number of points"); } break; case 2: if(du.length == 7) { Two.jisuan(du[1], du[2], du[3], du[4],du[5], du[6]); }else { System.out.print("wrong number of points"); } break; case 3: if(du.length == 7) { Three.jisuan(du[1], du[2], du[3], du[4],du[5], du[6]); }else { System.out.print("wrong number of points"); } break; case 4: if(du.length == 9) { Four.jisuan(du[1], du[2], du[3], du[4],du[5], du[6],du[7],du[8]); }else { System.out.print("wrong number of points"); } break; case 5: if(du.length == 9) { Five.jisuan(du[1], du[2], du[3], du[4],du[5], du[6],du[7],du[8]); }else { System.out.print("wrong number of points"); } break; } } }
可以看到我使用了switch-case来进行功能分类,将坐标传送到各个类中进行计算。
最后这道题也没有得到满分,原因同样是因为我没有进行进行完全的格式判断。
第三题:
第三题是在第二题的基础上进行扩展,将线推广到三角形,判断点与三角形,线与三角形的位置关系,以及对三角形周长,面积及重心等属性的求解。
所以这道题正常的类应该是一个point类,一个Line类,一个三角形类,三者自间呈递进关系,但是我在写这一题的时候仍然没有意识到应该这样创类,所以我还是创了五个计算类:

这是第三题的类图,从中可以看到我是如何建类,以及类之间的关系,除了建类,我认为此题的格式判断以及,选项四的计算也是一个难点,感觉又找到了高中做数学题的感受,下面是选项四计算的代码:
class Jiaodian{ void jisuan(double a,double b,double c,double d,double e,double f,double g,double h,double i,double j) { double x = c - a , y = d - b; double k = (d-b)/(c-a); double cha = x * f - y * e; double cha1 = x*h - y*g; double cha2 = x*j - y*i; if(cha >0&&cha1>0&&cha2>0||cha<0&&cha1<0&&cha2<0) { System.out.print(0); }else { if(f-b == k*(e-a)&&h-b == k*(g-a)||j-b == k*(i-a)&&h-b == k*(g-a)||f-b == k*(e-a)&&j-b == k*(i-a)) { System.out.print("The point is on the edge of the triangle"); }else { if(f-b == k*(e-a)||h-b == k*(g-a)||j-b == k*(i-a)) { System.out.print(1); }else { System.out.print(2); } } } } }
我将直线上的点带入三角形的三边,判断点是否也在三角形三边上,来确定直线与三角形是否有交点。很显然,这块代码并不能有效的求出交点个数,以及由两个交点分隔的两块三角形的面积。
三. 踩坑心得
看了上面这么长篇幅的代码分析,大家应该也知道了我几个踩坑的点
(1) 数据类型的错误,应该是float,还是double,做题前真的要认真分析一下,不然这可能就是阻挡你成功的障碍
(2) 如何对问题进行分类,不会有效的分析并写出正确的类从而使代码逻辑混乱,结构错误
(3) 对输入字符串的格式判断,一直是一个磨人的部分,当然现在新认识了正则表达式,以后可以尝试使用正则表达式进行解题
(4) 计算时,算法的优化,简化不能对问题进行有效求解
(5) 定义数组后,不经意间数组救回越界,导致编译出错
以上五点包括了我每一道题目高频踩坑的点
四. 改进建议:
(1) 第三次作业对于格式判断的代码:
if(str.charAt(i) == '+'&&str.charAt(i+1) == '+'||str.charAt(i) == '+'&&str.charAt(i+1) == '-'||str.charAt(i) == '-'&&str.charAt(i+1) == '+')
{
System.out.print("Wrong Format");
break;
}
If语句且不能判读出全部情况:
建议:可以使用正则表达式进行判断,可有效减少代码量以及错误率
(1) 第二次作业第二题:
对字符串进行解析,原代码:
if(number.charAt(i) == '0'&&i+10<number.length()&&number.charAt(i+9)=='1'&&number.charAt(i+10)=='1'&&count%2 == 0)
{
for(int j = i+1;j<=i+8;j++)
{
if(j == i+1)
System.out.print(cnt+":");
System.out.print(number.charAt(j));
}
是逐个输出字符,可改进为使用String.Split()对代码进行分隔输出。
(3)对所有作业类的优化:
以第三题为例:第一题:可建立一个point类,一个format类,分别进行求点计算及格式判断功能
第二题:可以借用第三题的point类,format类,再增加一个line类,进行直线的计算和判断
第三题:同样可借助前两题的point类,line类,format类,及三角形类,对三角形的有关计算和判断进行处理
(java学习中我对类的把握并不十分精准,还需再花时间学习)
五. 总结
(1) 学习心得:
在本阶段三次实验中,熟悉了java基本语法的使用,如:输入输出的语法格式,如何创建一个数组,以及使用switch-case的使用等。对字符串类的使用和功能有了更深的了解,以及如何对一个问题分类,类之间的联系如何,有了更近一步的了解
(2) 需要更近一步研究的地方:
还需要花更多的时间到研究如何分类以及如何判断输入格式是否正确上,然后尽量避免之前所踩得坑,可以通过多阅读代码,学习类之间的关系进行改进。
(3) 对于作业:
(浅浅吐槽一下:)
格式判断太磨人了!!!!!!!
相比较与上学期的作业,代码量及作业难度都有所增加,所以需要规划好时间,才可能上交一份满意的作业,其次对于作业,每次作业的格式判断部分都是占了很大比例,目前对类的使用也没有很多,并且题目中数学知识应用较多。
下一阶段继续加油。

浙公网安备 33010602011771号