其他分享
首页 > 其他分享> > 第二阶段学习总结

第二阶段学习总结

作者:互联网

前言:

  在这第7到10周这4周的时间里,在面向对象这门学科上我们所学得的内容确实不算多,但是所学得知识确实更加深奥难懂,虽然如此,我们在实际的作业当中也是有实际运用过一部分的,在这前言中先总结以下这4周来所学的知识点吧。在这四周中开始的那部分时间里我们主要是涉及到了用java写出C语言中的链表功能,并且这java中虽然是原本就有着容器这一可以代替链表这一功能的工具,但但我们需要的是在不使用这个功能的情况下实现链表的功能。在这四周中我认为比较重要的所学到的一个知识点就是正则表达式,正则表达式的内容其实还是不算少的,因此我也并不是学到了许多,只是在做作业的过程中当出现需要用上正则表达式或者用正则表达式会让代码编写更容易时才临时上网查找相关资料以此来边学边用。还有便是对继承与多态的加深理解与运用吧。在这几周所布置的作业来看,作业量倒是没有之前那般多,但是难度确实大为地提升了,尤其是有一些题目更是需要一题就做一天甚至更多时间。

 

设计与分析:

先来说说我认为较为简单的这次其中考试的题目分析吧。

在这几周中我们终于有了java的一次考试检测,时间限制是两个半小时,题目总共有三道,并且这三道题目还是递进式的,也就是说,第一题的题目是在第一题的题目上进行的改进,而第三题有时在第二题的题目上进行的改进。因此若是连第一题都不会或者没做出的话,那这次的其中考试也就炸了吧。但还好题目的难度不算太大,我除了在做题目时犯了点马虎错误之外,其他都十分顺利地写了出来。下面就有我来细细说明与分析这次考试的题目吧。

 

 

第一题类图如上,这题所设计到的知识点仅仅只是聚合而以。在这道题目中我是通过在main函数中new了两个point之后传入到line之中,两个point赋值给了line的两个point类型的私有属性,而代码如下,这还是比较简单的,其中两个point的display方法也是在line中的display中调用,因此,我在main中只需要调用一次line的display方法即可。

 

 

 

接下来的第二题的类图如下:

 

 

 

 

 

 

 

 

 这题进阶的题目用上了继承与多态,题目中是创建了一个Element抽象类,而无论是line还是point以及plane都是这个抽象类的子类,而在这个抽象类中则定义了一个display方法由三个子类共同继承。

 

 

 这回我的main中的代码如上所示,我是也是如同第一题的写法差不多,创建了两个point之后传入line中。但在这个继承与多态中有所不同的是:我new一个element变量,之后我又是将按照题目所示的样例一样将依次将原先new出的element的子类赋值给element在调用display方法,从而完成了这道题目。

第三题类图如下:

 

 

 

 

 

 

 这道题目倒是不如前面那两道题目那么好做我这回用上了容器的方法,将依据输入数字所选择的创建对象都传入我所new的go中,再在最后使用for-each遍历go中的每一个成员在一次调用display方法,最终得到结果。但是我在这一题中遇上了麻烦,经过我多次检查我才发现原来是我在对输入的index参数的判断时判断错误,导致我这道题目卡了好久。做完之后我对我自己都是大为无语,看来马虎不得啊,一旦马虎就可能导致卡好久。看来以后做题目需要多加注意了。

 

接下来我们来分析PTA上的题目集

在这几周的PTA题目集倒是没有之前布置的那么多,但是难度却是大为提升了。

先讲解题目集6吧,在题目集6中倒是难度不大,其中基本上是正则表达式的题目,主要目的就是让我们学习正则表达式的用法。

 

 

 这便是第一题的全部代码,很简单吧,主要就是让我们第一步接触正则表达式。其中[0]{1}\\d+就是判断开头是否为0,前面的s.length()则是判断输入的字符串长度是否符合条件。

 

接下来的第二题:

 

 

 

 

 代码依旧简单,我是通过输入字符串之后将其赋值给StringBuilder的str,用了StringBuilder就可以对字符串中的每一个字符进行查找与调换位置等之类的操作。

 

 

 

 

 第三题如上所示,我们分析匹配内容。{0-9A-Za-z]{4}}的理解就是匹配输入的字符串是否是数字、大写字母或小写字母,并且总数是否为4个。

在之后我们有一道bank类题目,要求如下:

 

 

 其中我对输入错误进行分析:

①输入错误处理  如果输入卡号不存在,则输出“Sorry,this card does not exist.”。

 如果输入 ATM 机编号不存在,则输出“Sorry,the ATM's id is wrong.”。

 如果输入银行卡密码错误,则输出“Sorry,your password is wrong.”。

 如果输入取款金额大于账户余额,则输出“Sorry,your account balance is insufficient.”。

 如果检测为跨行存取款,则输出“Sorry,cross-bank withdrawal is not supported.”。

对于以上的错误判断点则是需要依次判断,由上到下来进行判断。

 

接下来分析本次的重点题目:PTA上的图形类题目,就是这些题目花费了我大量的时间与精力,要求如下:

 

用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。
2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a quadrilateral or triangle"。
后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y
5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。

 

其实说句实话,这边的题目在编程上其实是并不难的,难的地方主要就是在这题目中的对图形的判断。这里需要用上大量的数学知识,在这题中的每一个判断我基本上都要临时查找资料来确定使用方法。

在这里我写了一个比较好用的类,可以将判断错误输入在这个类中完成。

代码如下:

 

 

 

 

 我在这题中的做法是将一行输入的字符串用空格分割,代码如下:

 

 

 我在这用上了一个容器list,类型是coordinate,目的是匹配到空格之后将这字符分割,随后一个个加入到coordinate中每一个coordinate都是加入了一个坐标,随后在这个类之中对输入的坐标是否合法在进行判断,若是判断结果为有误,则直接System.exit(0);来结束整个程序。不过这里需要注意的是要排除开头是空格的情况,否则程序会报错。

下面对每一个判断条件进行分析:

 

 

1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。
2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a quadrilateral or triangle"。
后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y
5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。

 

第一个判断是判断输入的四个点所构成的图形的邻边是否斜率相等,若是相等,则不可构成四边形。

第二个则是判断则是在判断是否为四边形的基础上判断对边是否斜率相等,若是,则是平行四边形,判断四边相等则为菱形,在判断邻边斜率,若出现方向向量相乘为0的情况则表示垂直,垂直则可能是矩形或正方形。

判断凹凸性则为以下代码:

 

 通过这种方法就可以判断。

方法为

  如果M在ABCD内部,则ABCD任意一点和M所构成的向量在改点所在边的中间,即叉积的乘积<0。如下:

       AB × AM  * AM × AD<0

       BC × BM  * BM × BA<0

       CD × CM * CM × CB<0

       DA × DM * DM × DC<0

对于这道题目,虽然方法是知道,但能不能完整得写出来又是另一回事了,因为在这道题目中用上了大量的数学知识,不仅如此,在这之中还隐藏着许多的坑点,一不小心就会落入坑中并且很难爬出。

 

之后我们再分析链表题目,对于这一道题目我认为是重点。

在这链表中我实现了一个接口,目的就是能够让人一眼就知道我的代码中主要有哪些方法。

 

  在这之中写了一个节点类,而在主要实现链表的类之中就是设置了head,curr,tail。head就是在链表的头节点,我的代码在增加链表成员时时在head之后开始加入第一位,那么对于我的最终链表输出时也是从head的下一位开始输出的。

输出方式如下:

 

 而对于curr则是主要用在了add和remove上,对于add来说,我是将原先已经建造的链表通过不断地读取下一位找到需要增加的节点部分的前一个节点,然后再创建一个新node,在新node中将需要的内容输入赋值之后对它的previous接入到前一个节点上,而对它的next则赋值为下一个节点。一次来实现链表的add。其中若是要增加最后一个节点上的成员,则可以调用另一个add,因为另一个add就是在最后一位增加成员。

当我在增加节点的过程之中,我就在每一次的add的最后一个节点的next赋值为null,然后再赋值为tail,因此实现了一个尾节点,在最后的print中则是从head的next遍历到tail的previous为止。

给出代码或许更好理解:

package LList;

public class LList<E> implements DoubleLinkedListImpl<E> {

private Node<E> head;// 头结点,非第一个节点
private Node<E> curr;// 当前节点
private Node<E> tail;// 最后一个节点
private int size;// 当前链表节点数

public LList(Node<E> head, Node<E> tail) {
this.head = head;
this.tail = tail;
}

public boolean isEmpty() {
if (this.size == 0) {
return true;
} else {
return false;
}
}

public int getSize() {
if (isEmpty()) {
System.out.println("this list is empty");
}
return this.size;
}

public E getData(int index) {
if (isEmpty()) {
System.out.println("this list is empty");
return null;
}
if (index < 0 || index >= size) {
System.out.println("invalid index");
return null;
}
curr = head;
for (int i = 0; i <= index; i++) {
curr = curr.getNext();
}
System.out.println("该位置成员为:" + curr.getData());
return curr.getData();
}

public void remove() {
if (isEmpty()) {
System.out.println("this list is empty");
return;
}
curr = head;
while (true) {
if (curr.getNext() == tail) {
break;
}
curr = curr.getNext();
}
curr.getPrevious().setNext(tail);
tail.setPrevious(curr.getPrevious());
size--;
}

public void remove(int index) {
if (isEmpty()) {
System.out.println("this list is empty");
return;
}
if (index < 0 || index >= size) {
System.out.println("invalid index");
return;
}
curr = head;
for (int i = 0; i < index; i++) {
curr = curr.getNext();
}
Node<E> R = curr.getNext();
curr.setNext(R.getNext());
curr.getNext().setPrevious(R.getPrevious());
size--;
}

public void add(int index, E theElement) {
if (isEmpty() && index == 0) {
add(theElement);
} else if (index < 0 || index > size) {
System.out.println("invalid index");
return;
} else {
curr = head;
for (int i = 0; i < index; i++) {
curr = curr.getNext();
}
curr.setNext(new Node<E>(theElement, curr.getNext(), curr));
size++;
}
}

public void add(E element) {
if (size == 0) {
head.setNext(tail);
}
curr = head;
while (true) {
if (curr.getNext() == tail) {
break;
}
curr = curr.getNext();
}
Node<E> node = new Node<E>(element, null, null);
node.setPrevious(curr);
node.setNext(tail);
tail.setPrevious(node);
curr.setNext(node);
this.size++;
}

public E getFirst() {
if (isEmpty()) {
System.out.println("this list is empty");
return null;
}
System.out.println("第一位成员为:" + head.getNext().getData());
return head.getNext().getData();
}

public E getLast() {
if (isEmpty()) {
System.out.println("this list is empty");
return null;
}
System.out.println("最后一位成员为:" + tail.getPrevious().getData());
return tail.getPrevious().getData();
}

public void printList() {
if (isEmpty()) {
System.out.println("this lsit is empty");
return;
}
System.out.print("现在链表为:");
for (curr = head.getNext(); curr != tail; curr = curr.getNext()) {
System.out.print(curr.getData() + " ");
}
System.out.println("\n");
}

}

如上可以明白链表的原理。

踩坑心得:

在编写代码是要仔细,不能够马虎大意,不然就有可能会像我一样由于没即使发现问题而花费大量时间。

对于容器的使用,要尤其注意泛型,泛型的类型是什么,那么所加入的成员就应该是什么类型,不然会报错。

 总结:

对于这次的阶段总结我要说的其实不多,在java的学习中我发现现在越来越加入了逻辑思维,在许多的题目中都蕴含大量的逻辑思考,不只这些,其实还含有这大量的数学知识,我们平时所使用的数学对一些事物的判断方法在平时我们并没有深入理解,从而在编写代码是会遇上困难,因为我们写代码是需要弄明白它们的原理才能够做到很好的判断成功,不然你总是会在自己做完判断方法之后才发现并不完整,从而不能拿到满分。

标签:总结,输出,head,题目,学习,四边形,curr,第二阶段,输入
来源: https://www.cnblogs.com/cxtchen/p/16214691.html