目 录java
1 实验目标概述... 1git
2 实验环境配置... 1github
3 实验过程... 1算法
3.1 Magic Squares. 2编程
3.1.1 isLegalMagicSquare().. 2数组
3.1.2 generateMagicSquare() 3网络
3.2 Turtle Graphics. 5app
3.2.1 Problem 1: Clone and import 5框架
3.2.2 Problem 3: Turtle graphics and drawSquare. 5eclipse
3.2.3 Problem 5: Drawing polygons. 5
3.2.4 Problem 6: Calculating Bearings. 5
3.2.5 Problem 7: Convex Hulls. 5
3.2.6 Problem 8: Personal art 6
3.2.7 Submitting. 6
3.3 Social Network. 6
3.3.1 设计/实现FriendshipGraph类... 6
3.3.2 设计/实现Person类... 7
3.3.3 设计/实现客户端代码main(). 8
3.3.4 设计/实现测试用例... 8
3.4 Tweet Tweet 10
3.4.1 Problem 1: Extracting data from tweets. 10
3.4.2 Problem 2: Filtering lists of tweets. 10
3.4.3 Problem 3: Inferring a social network. 10
3.4.4 Problem 4: Get smarter 10
4 实验进度记录... 10
5 实验过程当中遇到的困难与解决途径... 11
6 实验过程当中收获的经验、教训、感想... 11
6.1 实验过程当中收获的经验和教训... 11
6.2 针对如下方面的感觉... 11
本次实验经过求解四个问题,训练基本 Java 编程技能,可以利用 Java OO 开。
发基本的功能模块,可以阅读理解已有代码框架并根据功能需求补全代码,可以。
为所开发的代码编写基本的测试程序并完成测试,初步保证所开发代码的正确性。
另外一方面,利用 Git 做为代码配置管理的工具,学会 Git 的基本使用方法。
基本的 Java OO 编程;
基于 Eclipse IDE 进行 Java 编程;
基于 JUnit 的测试;
基于 Git 的代码配置管理。
简要陈述你配置本次实验所需开发、测试、运行环境的过程,必要时能够给出屏幕截图。
特别是要记录配置过程当中遇到的问题和困难,以及如何解决的。
在这里给出你的GitHub Lab1仓库的URL地址(Lab1-学号):
https://github.com/ComputerScienceHIT/Lab1-1170400307
请仔细对照实验手册,针对四个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但无需把你的源代码所有粘贴过来!)。
为了条理清晰,可根据须要在各节增长三级标题。
问题理解:本问题要求实现判断一个nxn矩阵是不是一个幻方,而且理解一个针对n为奇数的幻方的生成算法。主要考察点:Java基本语法,文件读写,判断输入的合法性。
1. 读入文本。
InputStreamReader reader = new InputStreamReader(new FileInputStream(new File("src/P1/txt/" + fileName)),"UTF-8");
BufferedReader stream = new BufferedReader(reader);
2检查有没有非法字符,对于本题来讲,合法的字符只有’0’到’9’和’\t’。
if(test[i].contains(".") || test[i].contains("-"))
{
System.out.print("contais - or .");
return false;
}
3检查是否是方阵。检查每一行的字符数是否等于行数。
if(checkStrings.length!=row)
{
System.out.print("lines is not equal rows");
return false;
}
4以上条件都知足时再判断是否是幻方。
for (int i = 0; i < row; i++) {
sum[i]=0;
checkStrings=test[i].split("\t");
if(checkStrings.length!=row)
{
System.out.print("lines is not equal rows");
return false;
}
for (int j = 0; j < checkStrings.length; j++) {
result[i][j]=Integer.valueOf(checkStrings[j]);
}
for (int j = 0; j < row; j++) {
sum[i]=sum[i]+result[i][j];
}
}
for (int i = 0; i < row; i++) {
sum[i+row]=0;
for (int j = 0; j < row; j++) {
sum[i+row]=sum[i+row]+result[j][i];
}
}
sum[2*row]=0;
sum[2*row+1]=0;
for(int i=0;i<row;i++)
{
sum[2*row]=sum[2*row]+result[i][i];
sum[2*row+1]=sum[2*row+1]+result[i][row-1-i];
}
for (int i = 1; i <= 2*row+1; i++) {
if(sum[i-1]!=sum[i])
{
System.out.print("sums are not equal");
return false;
}
思路:使用罗伯法构造一个n为奇数的nxn幻方。罗伯法的算法为把1(或最小的数)放在第一行正中;按如下规律排列剩下的(n×n-1)个数:
(1)每个数放在前一个数的右上一格;
(2)若是这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;
(3)若是这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;
(4)若是这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在底行且最左列;
(5)若是这个数所要放的格已经有数填入,那么就把它放在前一个数的下一行同一列的格内。
该任务须要我去自主学习java的一个第三方画图方案Turtle,而且经过给出的现有的Turtle方法实现题目要求的画图任务,而且借助数学工具进行解题。
利用get clone命令行
这个函数的功能是画一个正方形。须要调用两个方法foward(int units)向当前方向画直线,长度是输入的数字,单位是内部规定单位。turn(double degrees)按照顺时针方向旋转画图方向。
这个任务包含几个小任务。
(1)calculateRegularPolygonAngle 计算正多边形的内角,(边数-2)/sides。
(2)int calculatePolygonSidesFromAngle(double angle)
这个方法和上一个相似,根据角度计算正多边形边数。
(3)drawRegularPolygon :调用calculateRegularPolygonAngle(sides)计算正多边形的内角为rotation,调用turtle.forward和turtle.turn进行前进和转向。
calculateBearingToPoint :计算(当前点,当前朝向)构成的向量与(当前点,目标点)构成的向量之间的夹角,首先计算(当前点,目标点)构成的向量与y轴之间的tan,使用Math.atan2计算与y轴夹角,与当前朝向夹角(与y轴之间)做差计算两向量之间的夹角,须要注意负角变正角。
calculateBearings:对列表中的每两个相邻节点调用calculateBearingToPoint计算夹角。
这个是运用凸包算法。即对于一组输入的平面点集,求一个最小的集合组成的凸包,使这个凸包的全部点组成的凸多边形能够围着全部的点。
我采起的是gift-wrapping算法,这个算法形象的理解是,先选取一个一定在凸包里的点做为起点,这个点能够选取纵坐标最小的点(当存在多个纵坐标最小的点时,选取其中横坐标最小的点)。而后想象用一根绳子从起点出发,把平面上的全部点牢牢的围在一块儿,这条绳子上的拐点就是凸包上的点。
个人设计值得注意的几点是
1将输入的存放点集的set改为数组,方便操做
2经过向量叉积判断向量方位,例如A*B当A须要逆时针才能转向B时,A*B的值是正的。
利用以下指令,借助函数改变绘画形状和颜色:
public static void drawPersonalArt(Turtle turtle) {
for (int i = 0 ; i < 1500; i++) {
turtle.forward(i/2);
switch ((i/15) % 10) {
case 0:turtle.color(PenColor.BLACK);break;
case 1:turtle.color(PenColor.GRAY);break;
case 2:turtle.color(PenColor.RED);break;
case 3:turtle.color(PenColor.PINK);break;
case 4:turtle.color(PenColor.ORANGE);break;
case 5:turtle.color(PenColor.YELLOW);break;
case 6:turtle.color(PenColor.GREEN);break;
case 7:turtle.color(PenColor.CYAN);break;
case 8:turtle.color(PenColor.BLUE);break;
case 9:turtle.color(PenColor.MAGENTA);break;
}
turtle.turn(91);
}
}
利用git push命令行
该任务是须要我去创建一个图,经过输入搭建有向社交网,而且给出正确的输出,对非法输入进行正确的判断。
我采用的是邻接表的展现结构,效率较高。在List类型内装入Person类型,并且每个Person内有List存储每个人的序号
对于求出两个person之间的距离,先调用方法 calculateDistance
private void calculateDistance(Person name1){
int size = name1.getIdSize();
List<Integer> id = name1.getId();
for(int i = 0; i < size; i ++){
Person person = nameList.get(id.get(i));
if(!person.getKnown()){
person.setDistance(name1.getDistance()+1);
person.setKnown(true);
calculateDistance(person);
}else{
if(name1.getDistance()+1<person.getDistance()){
person.setDistance(name1.getDistance()+1);
}
}
}
}
这个方法以一个person为起点进行深度优先搜索,标记搜索过的点,并记录距起始搜索点的距离,而后经过getDistance方法得到两个person之间的信息,若是另外一个person的distance是0,说明是同一个点,若是未搜索到,说明无关系,返回-1。
Person设计尽可能知足如下几点
1成员变量设置成private,成员变量的访问是经过成员方法进行的
2知足FreindshipGraph的要求
如下是源代码
public class Person{
private String name;
private boolean known;
private int distance;
private List<Integer> id = new ArrayList<>();
public boolean getKnown(){
return known;
}
public int getDistance(){
return distance;
}
public void setDistance(int Distance){
this.distance = Distance;
}
public String getName() {
return name;
}
public void setKnown(boolean flag){
known = flag;
}
public List<Integer> getId(){
return id;
}
public int getIdSize(){
return id.size();
}
public boolean existId(int id){
if(this.id.contains(id)){
return true;
}
return false;
}
public void setId(int p) {
Integer P = new Integer(p);
this.id.add(P);
}
public Person(String name){
this.name = name;
}
}
客户端代码实验文档已经提供
FriendshipGraph graph = new FriendshipGraph();
Person rachel = new Person("rachel");
Person ross = new Person("ross");
Person ben = new Person("ben");
Person kramer = new Person("kramer");
graph.addVertex(rachel);
graph.addVertex(ross);
graph.addVertex(ben);
graph.addVertex(kramer);
graph.addEdge(rachel, ross);
graph.addEdge(ross, rachel);
graph.addEdge(ross, ben);
graph.addEdge(ben, ross);
System.out.println(graph.getDistance(rachel,ross));
System.out.println(graph.getDistance(rachel,ben));
System.out.println(graph.getDistance(rachel,rachel));
System.out.println(graph.getDistance(rachel,kramer));
主要对计算距离的算法进行了测试。
public void GetDistanceTest() {
FriendshipGraph graph = new FriendshipGraph();
Person rachel = new Person("Rachel");
Person ross = new Person("Ross");
Person ben = new Person("Ben");
Person kramer = new Person("Kramer");
Person abc = new Person("abc");
Person def = new Person("def");
Person hij = new Person("hij");
Person lmn = new Person("lmn");
graph.addVertex(rachel);
graph.addVertex(ross);
graph.addVertex(ben);
graph.addVertex(kramer);
graph.addVertex(abc);
graph.addVertex(def);
graph.addVertex(hij);
graph.addVertex(lmn);
graph.addEdge(rachel, ross);
graph.addEdge(ross, rachel);
graph.addEdge(ross, ben);
graph.addEdge(ben, ross);
graph.addEdge(rachel, def);
graph.addEdge(def, rachel);
graph.addEdge(abc, ross);
graph.addEdge(ross, abc);
graph.addEdge(hij, ross);
graph.addEdge(ross, hij);
graph.addEdge(lmn, ben);
graph.addEdge(ben, lmn);
assertEquals(1, graph.getDistance(rachel, ross));
assertEquals(2, graph.getDistance(rachel, ben));
assertEquals(0, graph.getDistance(rachel, rachel));
assertEquals(-1, graph.getDistance(rachel, kramer));
assertEquals(2, graph.getDistance(rachel, abc));
assertEquals(1, graph.getDistance(rachel, def));
assertEquals(2, graph.getDistance(rachel, hij));
assertEquals(3, graph.getDistance(rachel, lmn));
}
getTimespan:
若是tweets为空则将当前时间做为始末时间点构造Timespan,不然调用getEarliestTime和getLatestTime分别得到全部tweets中的最先发表时间和最晚发表时间构造Timespan。时间比较调用Time.isBefore和Time.isAfter函数。
getMentionedUsers
检测tweet的text部分,先找到字符@,而后检测@前一个字符,当不是有效字符时,记录@后面的有效字符,便是咱们要找的字符串。
writtenBy:for循环检查全部tweet,获取username,而后和咱们的字符串比较,相等即匹配成功。
inTimespan:利用Time.isBefore和Time.isAfter进行比较。
containing:先利用toLowerCase函数把推文内容和待查找字符串都转化为小写字母形式,而后直接调用contains函数进行检查。
guessFollowGraph:第一种证据思路是若是一名author在tweet中@过其余人,那么该author就会follow这些被@的人。扫描每条tweet,调用Extract.getMentionedUsers提取出该条tweet中全部被@到的人,将这些人加入到Map[author]->Set<Stirng>中。
public static List<String> influencers(Map<String, Set<String>> followsGraph)
influencers:按照社交网络的影响力(follow数目)对全部user进行排名。首先根据followsGraph统计每一个人的follow数目,再对每一个人的follow数目进行排名。
我采用的是最简单的寻找推文中的话题,利用话题的集合程度来表达两我的之间关系的亲密。
算法上和之间的寻找@的人物十分相似,咱们的主要目的是但愿找到两个具备相同话题的人,若是在此基础之上,两我的又有互相@的行为,咱们就能够断定为他们的关系不该该局限于“互相影响上面”,而有多是其余关系,例如朋友。
请使用表格方式记录你的进度状况,以超过半小时的连续编程时间为一行。
日期 |
时间段 |
任务 |
实际完成状况 |
2019-3-1 |
15:45-17:30 |
配置好实验环境和编译器 |
按计划完成 |
2019-3-5 |
15:45-17:30 |
完成项目1 |
延期1小时完成 |
2019-3-7 |
15:45-17:30 |
完成项目2 |
遇到困难,未完成 |
2019-3-10 |
15:45-17:30 |
完成项目3 |
提早一小时完成 |
2019-3-15 |
15:45-17:30 |
完成项目4 |
遇到困难,求助谷歌 |
2019-3-17 |
15:45-17:30 |
完成实验报告 |
按计划完成 |
遇到的难点 |
解决途径 |
对git使用不清楚
|
仔细阅读《git中文使用手册》 |
对于JAVA基本语法不熟悉
|
仔细学习《JAVA编程思想》 |
题目有点难度,错误比较多
|
逐次调试,改正bug |
1.关于JAVA的一些基础知识不会,网上也没有适合的资料,学习的过程浪费了一些时间。
2.题目是英文的,阅读起来有些难度,须要借助于网络工具,不少时候对题意的理解也有问题,很难下手。
3.本身的代码写的不好,没有章法,没有明确的思路,结构也很混乱,只能保证答案正确。
(1) Java编程语言是否对你的口味?
JAVA是世界上最好的编程语言。
(2) 关于Eclipse IDE
Eclipse是世界上最好的IDE。
(3) 关于Git和GitHub
Git和GitHub是世界上最好的代码交流项目。
(4) 关于CMU和MIT的做业
做业很难,作做业的过程很艰辛,经过作CMU和MIT的做业,我深入地认识到了本身和它们学生之间的差距,怪不得我考不上CMU和MIT。
(5) 关于本实验的工做量、难度、deadline
作完以后感受难度仍是有点大的,主要缘由在于本身第一次用JAVA,关于语法和算法的基础知识属于现学现用,,只能照葫芦画瓢,很艰难。
(6) 关于初接触“软件构造”课程
上课的内容和实验的内容有必定差距,不少实验内容要自学,目前基础太差,之后须要更加努力。