阶段性学习总结(二)
阶段性学习总结(二)
在这个第二阶段中,学习了继承与多态,抽象类与接口,还有Collections接口及其常用方法等,在PTA平台上也完成了一些习题以及每个礼拜的实验还有课堂上布置的链表作业等,于是笔者通过该篇随笔来对第二阶段面向对象程序设计这门课来进行总结。
PTA习题
这一阶段的PTA习题主要以图形类的设计为主,我认为这些作业还是具有一定的难度的,我也没有所有题目都取得满分,但我认为这样的几次作业很好的将编程与数学结合起来。在解决这些问题时首先得用数学思维来寻找解决方法,从而再需要通过编程来设计实现。
7-1 点线形系列1-计算两点之间的距离

点线形系列一是这系列题目的开端,但看题目要求计算两点间距离感觉比较简单,但是再判断输入格式是否符合要求时却成为了一大难题,后面便产生了用正则表达式来解决的方案,于是便现学现用正则表达式,从而成功解决了判断输入是否符合格式要求的问题。
7-2 点线形系列2-线的计算

点线形系列2-线的计算在点线形系列1-计算两点之间的距离的基础上在输入要求时增加了判断点重复这一要求,输入的坐标数也发生了变化,这也导致我们需要对原有的正则表达式进行修改,在计算数据时,通过用正则表达式提取数据再建一个数组来存储xy坐标的信息。前四个选项都比较简单,通过计算出每两点构成的直线的斜率再进行比较基本可解决问题,第五个选项我通过计算出两条线段交点的坐标,然后想根据如果点在两线段之内应当该点坐标既不是最大也不是最小这样来判断,可实际操作完之后却出现了有检查点不能通过的问题。
类图如下:

7-3 点线形系列3-三角形的计算

该题在原来几题的基础上,变成了计算与三角形相关的要求,思路上大概和前两题大同小异,但在难度上上升了一个档次
选项一通过计算出每条边的距离在进行比较判断出是什么类型的三角形。选项二直接运用重心公式便能求出。
选项三则判断每条边的平方的大小关系即可以判断出来。
类图如下:

7-2 点线形系列4-凸四边形的计算

相对于前几次的题目,这次的难度相对而言更记得大,首先判断输入的四个点能否构成四边形便是一个难点,经过分析,便总结出了四个点能构成四边形的条件,第一条便是任意三点不能共线且相邻的两个点连成的线段之间不能有交点。在判断三点共线时计算出每条线段的斜率再比较即可。判断两条线段之间没有交点可以利用java源码中的Line2D类中的intersectsLine()方法,可以简便快速的得到结果。有了是四边形的基础仅需判断对边的斜率是否相等即可判断出是不是平行四边形。
选项二中要判断是那种四边形,则要知道每种四边形的特点。比如菱形则是在平行四边形的基础上相邻两条边的长度相等,矩形则是在平行四边形的基础上有一个角是直角即可,正方形则是在菱形的基础上判断有没有角是直角,有则是正方形,没有则不是。
选项三判断凹凸四边形时可以利用面积法,将不相邻的两个点连线,再求出该线将四边形分成的两个三角形的面积之和,四边形有四个点可以求两次,将两次求出来的两个三角形之和进行比较,若相等则说明是凸四边形,不相等则说明是凹四边形。后面两个选型思想类似但是要考虑更多的情况,笔者的四五选项,并未全部完成,所以只分享到前三个选项。
链表类设计
随着课程的进展,老师在课堂上要求了用代码实现链表的功能,由于再学习C语言的时候链表这块内容掌握的不够扎实,在实现的时候也是费了不少的心思。
java实现单向链表
实现链表功能部分代码如下
package Java实现链表类; import Java实现链表类.LinearListInterface; public class LList<E> implements LinearListInterface<E> { private Node<E> head,curr,tail; private int size ; public LList() { head = new Node<>() ; tail = head; } @Override public boolean isEmpty() { if(size == 0){ return true; } else { return false; } } @Override public int size() { return size; } public int getSize() { return size; } public E get(int index){ if (index > size - 1 || index < 0) { System.out.println("数据不合法"); return null; } else { curr = head; for (int i = 0; i < index; i++,curr = curr.getNext()); return curr.getO(); } } public void remove(int index){ if (index >= size || index < 0) { System.out.println("数据不合法"); } else if (index == 0) { curr = head.getNext(); head = curr; size --; } else { curr = head; for (int i = 0; i < index - 1; i++, curr = curr.getNext()); Node<E> temp = curr.getNext().getNext(); curr.setNext(temp); size --; } } public void add(int index, E theElement){ if (index > size || index < 0) { System.out.println("数据不合法"); } else if (index == 0) { curr = head; head = new Node<>(theElement, curr); size ++; } else { curr = head; for (int i = 0; i < index - 1; i++, curr = curr.getNext()); Node<E> temp = curr.getNext(); curr.setNext(new Node<>(theElement, temp)); size ++; } } public void add(E element) { if (head.getO() == null) { head.setO(element); size++; } else { tail = head; while (tail.getNext() != null) { tail = tail.getNext(); } tail.setNext(new Node<E>(element, null)); size++; } } public void printList(){ curr = head; for (int i = 0; i < size; i++, curr = curr.getNext()) { if (i != 0) { System.out.print(", "); } System.out.print("第" + i +"个节点的值为 = " + curr.getO()); } System.out.println(); } }
测试功能代码如下:
package Java实现链表类;
import Java实现链表类.LList;
public class Main {
public static void main(String[] args) {
LList<String> list = new LList<String>();
//增加
System.out.println("增加元素");
list.add("0");
list.add("1");
list.add("3");
list.add("4");
list.printList();
System.out.println("列表的长度是" + list.size() );
//插入元
System.out.println("插入元素");
list.add(2, "2");
list.printList();
System.out.println("列表的长度是" + list.size() );
//删除
System.out.println("删除元素");
list.remove(2);
list.printList();
//查找
System.out.println("查找元素");
System.out.println("第三个元素是{" + list.get(3) + "}");
//越界测试
list.add(5, "越界元素");
System.out.println("第五个元素是{" + list.get(4) + "}"); //越界数据测试(边界值)
}
}
关于链表我想说的就是,链表的结构其实很简单,就是一个个节点连接在一起,形成一个完整的链条,每个节点包含2部分,数据域,和一个指向下一个节点引用的指针next,具体的更详细的大家可以参考相关资料解释,再说说删除操作,同样需要找到数据所在的位置,然后进行删除,不同的是,删除的时候,链表只需要改变一下前后节点的引用关系即可,就完成了节点的删除,而没有像数组那样触发一次全部数据的移动,从这个描述来看,链表在进行删除的时候,速度比数组快,根据这一点在一步一步地设计代码然后实现即可。
Java实现双链表
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
插入数据首先要对链表进行判空,如果链表为空则头节点 = 插入的节点 = 尾节点,不为空则1.将插入节点的Next指向头节点,2、调整头节点的前驱为新节点、3、将新节点设置为头节点4、size++
双向链表结构图:

期中测试题
在这个阶段的学习中进行了一次期中考试,这此考试题目我个人认为而言比较简单,都是基础的设计,题目中也给出了相应的程序类图,要求我们的代码符合类图,且测试的三道题都是层层递进的,后一题都是在前一题的基础上进行修改升级的。
7-1 点与线(类设计)

类图如下:

第一题比较简单,只需要根据题目,按照题目的要求一步一步将代码实现,注意输出的换行即可。
7-2 点线面问题重构(继承与多态)

类图如下:

第二题在第一题的基础上要求增加一个父类,以及新添加的Plane类,每个子类中都有其独有的getter and setter并也在每个子类中对父类中的display方法进行了重写,在这里也要求我们用到多态,所谓多态,就是在编译和运行时是不同的状态,在实现时都是先new出子类对象随后再定义一个父类的引用,将对象给到这个引用从而达到了使用多态的目的。
7-3 点线面问题再重构(容器类)

类图如下

第三题要求新增一个容器类,可以选择增加或删除对象等功能,这题要注意的点便是,在删除这个方法中,删除首先要对链表进行判空,因为节点是从0开始的所删除的时候是index - 1而且在判断范围时要去最后一个节点,不然便会出现错误。
该题的总体设计与前两题差别不大,总体而言比较简单。
总结
这一阶段的学习告一段落,学习是一个越学越难的过程,这从第一阶段的学习到现在也能体现出来,这一阶段学习的都是一些java源码里写好的东西,但是需要我们学会去理解去使用。这一阶段主要讲的便是Collections接口中的List接口,set接口,以及Map接口的使用,以及接触了一些比如朗姆达表达式,总体而言不算太难,但也不简单,需要平常多敲代码去熟练掌握,Java中的内容是无穷无尽的,需要我们不断地去学习,所以我也希望在下一个阶段的学习中,学到更多的东西,更加熟练的运用Java。下一个阶段将学习JavaFx等内容将要求我们能够图形化界面,以及还有内部类、异常等知识点,打牢基础相当重要,希望能将自己地基础打牢,能够到更高层次。

浙公网安备 33010602011771号