前言(作业分析)
本阶段有一个大作业以及一次期中考试,总结了对我来说比较有帮助的大作业中的一道题,以及期中考试三道题。
大作业中的题为正则表达式和计算几何的结合题,跟前几次的计算几何类似,并且难度加大了,剩下两题都比较简单,就不分析了。
期中考试的三道题是递进关系,主要考察了继承与多态,容器,抽象类和抽象方法。解题的思路比较清晰,但是在方法运用上要多想一下。
设计与分析
- 第四次大作业 -- 点线形系列4-凸四边形的计算
与前几次作业一样是考察正则表达式和计算几何,前几次作业都是采用斜率来计算,计算容易产生误差,本次采用了向量的方式来存点的数据,使用向量叉乘和向量点乘等向量的计算方法来减少计算产生的误差。
类图:
将函数专门化,首先正则表达式判断输入数据是否合格,将点存入数组。之后将点传参进get_vector函数进行向量运算,得到两点之间的向量坐标传回。
但是因为还没有进一步学习跨立实验和其他一些计算几何的方法,所以还是没有写完。
附一个跨立实验的图和码,浅学一下(码是C++的,原理都差不多)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 2100;
struct Point
{
double x,y;
}line[MAXN][2];
double mult(Point p0,Point p1,Point p2) //叉积计算,p0为公用节点
{
return (p0.x - p1.x) * (p0.y - p2.y) - (p0.y - p1.y) * (p0.x - p2.x);
}
//aa、bb属于同一个矩形 cc、dd属于同一个矩形 相交返回true,不相交返回false
bool Judge(Point aa,Point bb,Point cc,Point dd)
{
//判断两个形成的矩形不相交
if(max(aa.x , bb.x) < min(cc.x , dd.x)) return false;
if(max(aa.y , bb.y) < min(cc.y , dd.y)) return false;
if(max(cc.x , dd.x) < min(aa.x , bb.x)) return false;
if(max(cc.y , dd.y) < min(aa.y , bb.y)) return false;
//现在已经满足快速排斥实验,那么后面就是跨立实验内容(叉积判断两个线段是否相交)
if(mult(aa,cc,bb) * mult(aa,bb,dd) < 0) return false; //正确的话也就是aa,bb要在cc或者dd的两边
if(mult(cc,aa,dd) * mult(cc,dd,bb) < 0) return false;
return true;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
bool flag = true;
for(int i = 0;i < n;i ++)
scanf("%lf%lf%lf%lf",&line[i][0].x,&line[i][0].y,&line[i][1].x,&line[i][1].y);
for(int i = 0;i < n;i ++)
for(int j = i+1;j < n;j ++)
{
if(Judge(line[i][0],line[i][1],line[j][0],line[j][1])) // 判断两条直线是否相交
{
flag = false;
break;
}
if(!flag) break;
}
if(!flag) printf("burned!\n");
else printf("ok!\n");
}
return 0;
}
分析图:
有部分函数还是过于复杂,并且没有达到预期的使用效果,还有待加强。
- 期中考试 -- 点与线(类设计)
考察了一下类的设计,比较简单。分门别类写一下函数就行。
类图:
按照题目要求的类图写。
分析图:
没啥好说的这个,就是单一的按图写话。
- 期中考试 -- 点线面问题重构(继承与多态)
与前一个差不多,但是增加了继承与多态。增加一个Element类,使其他函数继承他的display(),进行输出。
类图:
要求为抽象类,隐藏属性。增加了一个平面的类。其他与第一题大致相同。所以也看图写话。但是抽象类和抽象方法我不是很懂,当时也没有正确使用这个类和方法,导致空写了一个abstract类。
分析图:
图表数据看起来还是很不错的,继续保持。
- 期中考试 -- 点线面问题再重构(容器类)
在第二题的基础上增加了增删改的功能,同时要求使用数据库,并且用容器类和泛型等,这个我当时真的没学到。救。
首先就是选项选择,用了switch...case的结构,同时增加了对输入点的坐标的判断。
点线面类基本不变,主要改动为主函数的选择结构,以及GeometryObject类的写法。用到了数据库结构里的add(),remove()。
输出部分使用了for...each语句,虽然还是挺不熟练的。
类图:
分析图:
部分函数复杂程度过高,书写不够简洁。
踩坑心得
- 大作业的计算几何确实让我学到了很多东西。首先是正则表达式的熟练运用,然后就是从计算斜率和b来算直线变成了用向量的方法来计算线与线的关系,线与图形的关系。寻求了一些同学的帮助,知道了计算几何是什么,然后进行了学习,目前来说还是没有学会,真的很难。
- 期末考试的泛型和容器类,抽象类和抽象方法都是我当时没有学会的,虽然测试点都通过了,但是没有正确使用到抽象方法和抽象类的定义方法,就是空用了一下,不算真正学会。在这里贴一下抽象类方法的书写格式
public abstract class Employee
{
private String name;
private String address;
private int number;
public abstract double computePay();
//其余代码
}
正确书写格式为()后加分号书写,并不是普通方法一样的花括号,这次作业我用的是花括号,所以并不是实际意义上的抽象方法。学习之后会加以改进。
- 泛型和Obeject类目前还在学习当中,等学完会在回来思考一下期中考试中最后一道题的写法。
改进建议
- 还是要多学多练,这几次的大作业确实让我感觉到了知识储备的不足,特别是计算几何这一个方面,要积极学习。
- 要紧跟老师上课的节奏,提前学习内容。
总结
总的来说这几周的学习不紧不慢,有收获但是还是不够,希望下次的大作业可以给出一个满意的代码。