BLOG-2 对7-10周的学习总结
面向对象程序设计---七到十周综合性学习
引言:过去几周的Java的学习经历了PTA大作业四,期中考试,还有两次实验。对遇见的题目和知识点进行整理和分析。
PTA大作业四
前言:这次的大作业共三道题。第一题是对正则表达式的考察,第二题考察四边形相关知识,第三题设计一个银行服务类。
对于正则表达式的学习会优化代码的结构,减少选择和循环对格式的判断。只需要规定正确的表达就可以规范化格式问题。
第二题则是本次作业的难点,要求用计算机语言来实现几何图形的判断,不仅是对编程能力的考察,更要求较高的数学能力和空间想象能力。写这道题可以充分体现出编程的特色,需要与数学缜密的结合。用计算机语言来严谨的转化数学语言,这可以有效的锻炼我们面对复杂需求下的编程实现。这道题对于初学者算是一道难题,不仅要求对常用的数学方法的代码表示,如向量叉乘,射线法,两直线相交求交点,判断凹凸多边形.......
第三道题则是根据类图设计出一个类,要求实现相关的功能,需要把握类与类之间的关系和其中的具体细节。
题目集得分:96 题目集用时:十小时以上。 题目难度:难(是我写过最难的题目了,以后还会更难)
各题目 设计与分析 踩坑心得 改进意见 核心代码分析:
(1)7-2 点线形系列4-凸四边形的计算
设计与分析:


这道题的代码量达到了五百行。这个题目有五分分支,每个分支难度递增又彼此不同。分支和代码量的增加直接导致代码的质量下降。
这是由于在做题目时只考虑如何实现代码的功能,为了写代码而去写代码,而没有考虑到代码的质量。这道题的难处之一在于输入检测。
我推翻了前几次的格式判断函数,用正则表达式的思想,不去管有多少种错误,而只需要通过一定的分支判断出正确的格式,屏蔽掉错误的格式
这次的格式控制不仅代码量大大下降,而且格式的控制更加的简便,而且这样的代码读起来会更加的容易理解。
踩坑心得:
这个题出题人为了避免四个点构成四个点的情况过多,规定输入的四个点两两相邻,避免了构成四边形情况过多,但是产生了新的问题。
比如判断是否构成四边形。
按照正常来说,是需要输入的点不是三点(四点)共线,就一定能构成四边形。
然而如果按照题目的输入要求,就不能判断所有的三点共线情况 。而是按照输入要求只能选择其中的一个问题,才可达到题目的要求。
而我一开始设计了所有的情况,反而是画蛇添足了。
这题所有的坑都来自非法输入(以下是我对于输入非法的一些样例)
1:+-2,001 3,1
2: 02.,3 1,2,3
3: 1+2,-0 1,2 (末尾有空格)
4:1, 1,,2
这题我被反复折磨,其实就是做重复的事情,由于没有提示测试样例的点,那我只能一步一步地去尝试。
在经过大量输入之后,我总结了以上的输入非法并对代码进行改进,直到通过所有的测试点。其中的难受真的时不想体验第二遍。
改进建议:
1、由图可知,该题的圈复杂度为73。这里有点可惜,如果小于10代码质量就会很好。改进可以减少循环的使用。
2、这题可以将获取字符串变成一个字符数组。此题可以将split方法改进,提高程序的执行效率
核心代码分析:
① 格式控制代码
static int is_format(int m,String str) { str = str.trim(); String []s =str.split("[ ,]"); int count=0 ,count1=1,sum=0; loop:for(int i=0;i<s.length;i++) { if(s[i].length()==0){ return 0; } for(int j=0;j<s[i].length();j++) { sum=0; char ch = s[i].charAt(j); if(j+1==s[i].length()) { if(ch=='+'||ch=='-'||ch=='.') return 0; if(ch>='0'&&ch<='9'&&i+1==s.length) break loop; else if(i+1!=s.length) continue; else return 0; } char ch1 = s[i].charAt(j+1); if(ch=='0'&&j==0){ if(ch1>='0'&&ch<='9') return 0; } if(ch=='+'||ch=='-') { if(j==0&&(ch1>='0'&&ch1<='9')) continue; else return 0; } else if(ch=='.'||ch1=='.') { sum++; if(((ch1<'0'||ch1>'9')&&ch=='.')||sum>2||((ch<'0'||ch>'9')&&ch1=='.')) return 0; else continue; } else if(ch>='0'&&ch<='9') continue; return 0; } } if(s.length==0){ return 0; } if(s.length!=m) { return -1; } if(s.length==m){ return 1; } return 0; }
②判断四个点是否构成三角形
static boolean IsSJX(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4) { double a = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); double b = Math.sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)); double c = Math.sqrt((x3-x4)*(x3-x4)+(y3-y4)*(y3-y4)); double d = Math.sqrt((x4-x1)*(x4-x1)+(y4-y1)*(y4-y1)); if(k(x1,y1,x2,y2)!=-100&&k(x2,y2,x3,y3)!=-100&&k(x3,y3,x4,y4)!=-100&&k(x4,y4,x1,y1)!=-100) {//四个点构成三角形 if((y2-y1)*(x3-x2)==(y3-y2)*(x2-x1)){ //点1,2,3共线 if(on(x2,y2,x1,y1,x3,y3)) //3 2 1 为什么是||而不是&&? // if(a+b+c>d&&c+d>a+b&&a+b+d>c) return true; } if((y3-y2)*(x4-x3)==(y4-y3)*(x3-x2)) { //2,3,4共线 if(on(x3,y3,x2,y2,x4,y4)) if(b+c+a>d&&b+c+d>a&&a+d>b+c) return true; } if((y4-y1)*(x1-x2)==(y1-y2)*(x4-x1)) //4 1 2 if(on(x1,y1,x4,y4,x2,y2)) return true; if((y4-y1)*(x1-x3)==(y1-y3)*(x4-x1)) //1 4 3 if(on(x4,y4,x1,y1,x3,y3)) return true; // return true; } if(k(x1,y1,x2,y2)==-100||k(x2,y2,x3,y3)==-100||k(x3,y3,x4,y4)==-100||k(x4,y4,x1,y1)==-100) { if((k(x1,y1,x2,y2)==-100&&k(x2,y2,x3,y3)==-100)||(k(x2,y2,x3,y3)==-100&&k(x3,y3,x4,y4)==-100)||(k(x3,y3,x4,y4)==-100&&k(x4,y4,x1,y1)==-100)||(k(x4,y4,x1,y1)==-100&&k(x1,y1,x2,y2)==-100)) return false; else if(a+b+c>d&&a+b+d>c&&a+c+d>b&&b+c+d>a) return true; } return false; }
期中考试
前言:期中考试时间比较紧张,只有两个小时,题目也是三个题目。但是这三个题目作为考试设计的非常的巧妙,题目承上启下,写起来重复的内容越来越少,而考察了最近学习的内容。
主要考察了继承,多态,接口,容器类,ArrayList ,set和get方法,泛类。
各题目 设计与分析 踩坑心得 改进意见 核心代码分析:
题目:7-1 点与线(类设计)
设计与分析:


踩坑心得:
这道题倒不是很难,不过需要理解类图中类之间的关系,才可以很好的解决这样的问题
代码的有些语句判断过长,可以将其拆分,增强观感
改进意见:
暂无。
核心代码分析:
这题是对点与线的类型设计。很好的阐述了类之间的设计
import java.util.Scanner; public class Main { } class Point{ private double x; private double y; public Point() { } public Point(double x,double y) { this.x = x; this.y =y; } public double getX() { return x; } public double getY(){ return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } public void display() { System.out.println("("+String.format("%.2f", getX())+","+String.format("%.2f", getY())+")"); } } class Line { private String color; private Point Point1,Point2 = new Point(); Line(){ } Line(Point Point1,Point Point2,String color){ this.Point1 = Point1; this.Point2 = Point2; this.color = color; } Point getPoint1() { return Point1; } Point getPoint2() { return Point2; } void setPoint1(Point Point1) { this.Point1 = Point1; } void setPoint2(Point Point2) { this.Point2 = Point2; } String getcolor(){ return color; } void setcolor(String color) { this.color = color; } String getDistance() { Double data = Math.sqrt((Point1.getX()-Point2.getX())*(Point1.getX()-Point2.getX())+(Point1.getY()-Point2.getY())*(Point1.getY()-Point2.getY())); return String.format("%.2f", data); } public void display() { System.out.println("The line's color is:"+getcolor()); System.out.println("The line's begin point's Coordinate is:"); Point1.display(); System.out.println("The line's end point's Coordinate is:"); Point2.display(); System.out.println("The line's length is:"+getDistance()); } }
这是第二题的类图

核心代码分析:
这道题附上运用多态的系列代码进行说明
public static void main(String []arge) { Scanner input = new Scanner(System.in); Double x1,y1,x2,y2; String color; x1 = input.nextDouble(); y1 = input.nextDouble(); x2 = input.nextDouble(); y2 = input.nextDouble(); color = input.next(); Point p1 = new Point(x1,y1); Point p2 = new Point(x2,y2); Line line = new Line (p1,p2,color); Plane plane = new Plane(color); Element element ; if((x1<=0||x1>200)||(x2<=0||x2>200)||(y1<=0||y1>200)||(y2<=0||y2>200)) System.out.println("Wrong Format"); else { element = p1;//起点Point element.display(); element = p2;//终点Point element.display(); element = line;//线段 element.display(); element = plane;//面 element.display(); } }
7-3 点线面问题再重构(容器类)
类图如下

这道题主要是书写一个容器类,用到ArrayList的add和delete方法做到增加和减少。
这个需要熟练的运用ArrayLIst的方法,对于Java课程的学习上课听讲有很好的检验效果。
而这道题的容器类只要理解好这个类图的类与类之间的关系,就很容易做出来了。
踩坑心得:

这就是我对ArrayList不熟悉导致的 我在删除的时候书写的代码时list.remove(index);
对比上图 我忘记了应该删除的是index-1而不是index导致这道题目的错误
这就很好的说明了我对Java的ArrayList不够熟悉,对于下标引用的不够熟悉,这说明我们在学习的过程中需要注意细节,差之毫厘,谬以千里。
在这里也给我自己一个警示,上课需要非常的专心。
改进意见:
1、如复杂度分析图所示,本题的圈复杂度为33,超过了代码的一般范围,这就意味这该代码的可读性非常的差,而对与前文提到的方法都可有效减少圈复杂度。
2、本题的代码有两百多行,代码的简化就显得尤为重要,应该适当的合适代码的逻辑,让代码模块化。
3、如果能够将代码的逻辑颠倒一下,程序将更加的合理。
核心代码如下:
class Plane extends Element{ private String color; public void display(){ System.out.println("The Plane's color is:"+getColor()); } Plane(){ } Plane(String color){ this.color = color ; } String getColor() { return color; } void setColor(String color) { this.color = color; } } class GeometryObject { ArrayList<Element> list =new ArrayList<Element>(); GeometryObject(){ } public void add(Element element) { list.add(element); } public void remove(int index) { if(index<list.size()) list.remove(index-1); } public void getlist() { for( Element element : list) element.display(); } }
这一排的代码很好的说明了如何书写容器类。
对于这接下来的代码书写有很好的借鉴作用。
switch(choice) {
case 1://insert Point object into list
输入“点”对象的x,y值
break;
case 2://insert Line object into list
输入“线”对象两个端点的x,y值
break;
case 3://insert Plane object into list
输入“面”对象的颜色值
break;
case 4://delete index - 1 object from list
输入要删除的对象位置(从1开始)
...
}
学习心得:
1、让我对自己的水平有了一定的认知,提醒我今后的学习还有很多改进的地方,领悟自上而下逐步细化的编程思想更加的透彻
2、深刻了解了关于Java程序结构和代码书写的规范,以及要遵守的代码书写规范,拔高了我对程序设计的眼界和深度,学习了很多编程时使用的技巧和方法
3、积累了一些debug的经验,深刻认识到了调试的重要性,学会了调试的基本技巧,如何设置断点,单步进入,跟踪参数,以及更改代码的逻辑顺序,排除逻辑错误,对提高代码的质量大有改善。
4、学会了对于一些类的使用,了解了如何使用实例方法,抽象方法,和包括ArrayList的使用方法,这对于今后的学习有很大的提示空间。
特别鸣谢出题目的老师和帮助我修改代码的同学们,让我有了提高自己的机会

浙公网安备 33010602011771号