一、首先对实验进行一个简单描述:
本次实验通过求解三个问题magic squares、turtle graphics、social network,训练基本 Java 编程技能,能够利用 Java OO 开发基本的功能模块,能够阅读理解已有代码框架并根据功能需求补全代码,能够为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。 另一方面,利用 Git 作为代码配置管理的工具,学会 Git 的基本使用方法。
基本的 Java OO 编程
基于 Eclipse/IDEA IDE 进行 Java 编程
基于 JUnit 的测试
基于 Git 的代码配置管理实验环境配置
二、实验遇到的问题和解决(重要)
1.实验第三部分用Person和FriendshipGraph模拟社交网络,其中的getDistance返回两人最短距离这个函数显然要用广度优先搜索的思想解决,我想到了一种稍微有些不同的解决方法。
调用contains()函数判断某个人的朋友是不是包含了目标p2,是的话就返回++dis,即找到了;不是的话就把这个人的所有朋友放进队列(已访问标记过的不放进去),在下个for循环中执行重复操作,每一层循环的对象就是上个for循环中所有人的未标记访问的朋友,每个for循环开始前先存储queue.size()以便于控制循环访问次数。
我认为这样写更简单易懂,就像蛋卷一样一层一层向外拓展,越到外面越大,里面最中心只有一个人,每一层都代表里面一层朋友的集合(用ture/false表示是否遍历过),每一层都没有contains成功就有dis++(距离++)。
beFalse()用于每次调用getDistance后将是否遍历过改为false
2.Magicsquare函数没想到如何判断数字是否重复出现
解决方法:创建一个static boolean[] rep=new boolean[N*N+1]用来表示数字n是否出现过,例如9出现一次就标记rep[9]=true;然后观察rep[square[rowNum][i]]的值来判断重复。
3.凸包问题出现了许多bug,以及起始点确定问题
解决方法:不断debug中发现起始点不只是x最小那么简单,应该保证y尽量小,这样便不至于有(1,1),(1,2)选择了(1,2)这样的错误。
public static Set<Point> convexHull(Set<Point> points) {
//throw new RuntimeException("implement me!");
if(points.size()<4)
return points;
Set<Point> ans=new HashSet<Point>();
Point left=new Point(Double.MAX_VALUE, Double.MAX_VALUE);
for(Point i:points) {
if(i.x()<left.x())
left=i;
else if(String.valueOf(i.x()).equals(String.valueOf(left.x()))){
if(i.y()<left.y())
left=i;
}
}
ans.add(left);
Point temp=new Point(0,0);
Point next=new Point(0,0);
temp=left;
double correction=0.0;
//double tem;
double max=360.0;
double mul=0.0;
for(Point i:points) {
if(i!=temp) {
if((Math.atan2(i.y()-temp.y(),i.x()-temp.x())*180/Math.PI)<max) {
max=Math.atan2(i.y()-temp.y(),i.x()-temp.x())*180/Math.PI;
mul=Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2);
next=i;
}else if((String.valueOf((Math.atan2(i.y()-temp.y(),i.x()-temp.x()))*180/Math.PI)).equals(String.valueOf(max))) {
double mul1=Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2);
if(mul1>mul) {
next=i;
mul=mul1;
}
}
}
}
ans.add(next);
correction+=max;
temp=next;
while(temp!=left) {
double angle;
double theta;
max=360.0;
mul=0.0;
for(Point i:points) {
if(i!=temp) {
angle=Math.atan2(i.y()-temp.y(),i.x()-temp.x())*180.0/Math.PI;
if(angle==0) {
if(ans.contains(i))
theta=(angle+(360)-correction)%(360);
else
theta=(angle-correction)%360;
}else
theta=((angle<0?angle+(360):angle)-correction)%(360);
//double r=Math.sqrt(Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2));
if(theta<max) {
max=theta;
mul=Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2);
next=i;
}else if(String.valueOf(theta).equals(String.valueOf(max))) {
double mul1=Math.pow(i.y()-temp.y(),2)+Math.pow(i.x()-temp.x(),2);
if(mul1>mul) {
next=i;
mul=mul1;
}
}
}
}
if(next!=left) {
ans.add(next);
correction+=max;
}
temp=next;
}
return ans;
}
从x最小的点起(x相同取y最小)逐个寻找极坐标下极角最小的点,若遇到两个极角相同的点,取距离更长的,最终遇到初始点时,凸包构造完成,返回即可。