目录链接
这次笔记我们记录一下实验里面遇到的疑问和针对它们的思考。由于写作此篇时笔者并未完成实验三,此处仅包含实验一、二的内容。
一、实验一
1.1 git的使用方法
在做实验一的时候遇到的第一个问题就是对git不了解。对于git学习我们在第三章已经做完,这里我们列举一下git的常用指令,如下所示:
pwd 显示当前目录
ls 显示当前文件夹目录
ls -a 显示当前文件夹所有目录(包括隐藏)
cd 跳转至某个目录
git init: 创建一个git仓库,把当前目录变成git可以管理的仓库
git status 显示所有变更的文件
git clone 下载一个项目和它的整个代码历史
git log 显示当前分支的版本历史
git config --list 显示当前的git配置
git add [file1] [file2] 添加文件到暂储区
git add . 添加当前目录的所有文件到暂存区
git add [dir] 添加指定目录到暂存区,包括子目录
git rm [file1] [file2] ... 删除工作区文件,并且将这次删除放入暂存区
git commit -m [message] 提交暂存区到仓库区
git commit [file1] [file2] ... -m [message] 提交暂存区的指定文件到仓库区
git commit -a 提交工作区自上次commit之后的变化,直接到仓库区
git log --stat 显示commit历史,以及每次commit发生变更的文件
git push [remote] [branch] 上传本地指定分支到远程仓库
git pull [remote] [branch] 取回远程仓库的变化,并与本地分支合并
git push [remote] --all 推送所有分支到远程仓库
git push -u origin master 仓库关联
git push 远程仓库的提交(第二次及之后)
1.2 JUnit的使用方法
初次做实验时,我并不明白怎么设置JUnit路径。JUnit使用方法如下:
首先从官网上下载JUnit下载包,如果是eclipse一般自带junit3,4,5。
然后重点的部分来了,打开项目的属性,点进Java构建路径中的库部分,在类路径中添加对应的JUnit包,如下图所示:
注意一定要添加进类路径中。
此时Java会引用JUnit系统库,不要忘了放到lib文件夹中。
1.3 调整程序路径的方法
在实验1中,我们需要直接导入外部的程序,而最终我们形成的程序要分src、test文件夹等,这些也决定着我们具体引用哪个对应的包。这项内容十分重要,我们该如何调整程序路径呢?
笔者采用了如下的方法,首先点进项目文件夹中,将里面的文件结构先用复制粘贴变成要求的文件结构;
然后打开项目的属性,点进Java构建路径中的源码部分,并添加新的源文件夹,如图所示:
这样即可把我们想要添加的文件夹,如test等,添加入源码部分,这样即可在源文件和测试文件之间建立联系了,如图所示:
1.4 读取幻方时遇到的问题
在按照教材的说明,写完代码开始读取幻方文件给的5.txt时,我发现Java报了一个错误,显示java.lang.NumberFormatException
。这究竟是为什么呢?
顺着执行跟踪,我找到了对应代码的问题,就出在那个方法,Integer.valueOf
上。它只会把全是数字的字符串转化成对应的Integer格式。我们在做这个转化之前,需要按照指导书的要求,将每一个元素按照行和\t全部分离开。在这个地方报错,可以确定文档里一定出现了除了数字、分行符\n、分隔符\t之外的东西。打开5.txt,果不其然,如下所示:
指导书中要求我们必须对于这种输入能够做出反应并返回false,因此我在这里用了try-catch捕捉了弹出的此次错误,如下:
try {
for (int i = 0; i < m; i++) {
ms[n][i] = Integer.valueOf(l2[i].trim());
if (ms[n][i] <= 0 || is[ms[n][i]]) {
br.close();
return false;
} else
is[ms[n][i]] = true;
}
} catch (java.lang.NumberFormatException e) {
return false;
}
这样就可以了。
1.5 解决重名问题
我们在写朋友关系图的实验时,需要解决重名问题。
这里说的重名问题可不是简简单单的变量名相同问题,而是person类中name变量不相同的问题。因为在要求中包括了一种输入:变量名和name变量存的字符串不同的情况。这就导致了可能会有name相同、变量名不同的person存在。如何才能解决这个问题?
正常能想到的方法就是在类中添加一个容器作为名表,每次加入新人时如果不与重名表中的人重名,就把他的名字加入容器中。众所周知,set中不能存在相同元素,因此用来存这东西真是非常合适。代码实现如下:
public boolean addVertex(Person a) {
if (names.contains(a.getname())) {
System.out.println("There is already a " + a.getname());
System.exit(0);
}
names.add(a.getname());
adj.put(a, new ArrayList<Person>());
return true;
}
要注意在初始化set的时候,不要加上static修饰,这样违反了实验指导书的要求。
1.6 无法完成测试?
在解决上述重名问题之后,我们很快地遇上了下一个问题:测试无法完成。
因为我们在测试这个重名情况时,程序会发生exit(0)
导致无法完成测试。我实在是百思不得其解,因为exit(0)
会导致无法通过测试,而不exit(0)
又违反了实验指导书的要求。实在是进退两难的情况。
最终我还是在把exit(0)
改成return false
跑完了测试。
二、实验二
2.1 带不带符号?
我认为第一个问题的指导有一点歧义。在写第一个问题的第五个小问题“诗意地散步”中,要求我们完成graphpoet
类。在这个类中,我们需要调用函数,读取文件中的部分,完成语料库的构建;按直觉考虑,我的语料库中的元素应该不包含符号内容;但是按照mit的官方指导,语料库中的元素应该是包含符号内容的。
这一点非常令人迷惑,如果带符号存储的话,由于我们以空格分开单词,这样会导致语料库存储下(单词+符号)这样的节点。假如我要在两个单词之间添加其他词语,就会因为符号的存在而无法添加。举个例子:
语料库导入文本:I like hard studing in the class room.
输入诗句:I like studing.
这种情况下的hard就会因为studing后面的符号而无法加入输出的字符串中。
无论如何,我最终还是采用了mit的官方要求的写法,保留了符号。代码如下:
line = input.split(" ");
words.addAll(Arrays.asList(line));//把输入字符串改成单词形式
这样应该就可以了。
2.2 又无法完成测试?
这次由于重写实验1的问题3,我又遇上了这个问题。由于这一次重点在测试上,因此我这次让程序返回了false并且输出了错误信息,最终提交了这个版本。
三、总结
实验中遇到的比较大的问题就这些。这些问题中还是有至今没有解决的,不过似乎也不应该太过于纠结这些问题了,从问题中总结经验才是正确的行为。