lab2回顾——P1(Poetic Walks)(补充)

这几天又想到一些感悟,故特地来补充一下。

正文

lab2的主题为ADT&OOP。所谓ADT,就是实现一个抽象的数据结构,利用@override来重写其方法,并且在每次实现方法之后都要利用方法来检查其是否仍满足此数据结构。OOP是面向对象,包括接口、继承和多态这些概念。

lab2分为了P1和P2两部分来解决。其中P1大概意思是让我们亲自动手建立一个ADT,P2是对lab1中的人际关系网进行功能的优化和拓展。

本着测试优先的原则,一上来的problem就是先写类vertex和edge的测试用例。在代码示例中,已经有 这些方法的规定了,我们只需要根据这些方法来写测试用例就行。但是在L中并没有给出方法,需要我们自己去想一些方法。当然getter、setter、equal、tostring和hashcode是必须的,除此之外还要想一些别的方法,以及它们的测试用例。

接下来是完善两个类——vertex和edge。

刚开始是用String来代表它们的参数类型,后来逐渐减少属于String的方法至没有,而转为泛型L。这里的泛型实际上在客户端里可以用任何数据类型来代替,比如int、String、double、float、Interger、long等类型。所以L的方法是一定可以适用于这些类型。

在编写这个类的过程中,需要一个AF/RI方法checkRep来在每次return前对数据的合法性进行检测。如果检测不通过则会抛出一个项异常,说明这个方法对数据L的内部进行了修改,说明其不符合我们的需求条件。

在程序编写过程中还需要时刻注意对可变数据类型的安全性防范:比如防御性拷贝、字段设为私有等……

这就涉及到ADT的基本知识了。一个合格的ADT可分为4部分:

a. creators(构造器)
b. producers(生产器),从旧的对象中创造新的对象
c. observers(观察器),获得对象中的各种属性
d. mutators(变值器),改变对象属性的方法

而我们作为开发者,应当尽可能的满足客户端的需求,同时也不能掉以轻心,要时刻防范客户端的某些操作给我们的程序带来潜在的风险。

完成了以上部分,就可以利用这个图来“生成诗歌”了。

接下来其实就是poetwalk类的编写。

其实我觉得这部分才真正让我体会到了coding的乐趣。

之前的部分要么就是写测试,要么就是在想各种各样的异常状况(健壮性),没有解决问题的乐趣,总感觉缺少了某些“灵魂”。直到遇到了这个问题,我才重新找回了真谛——是因为main()函数回来了。

(以下删除线部分为刚开始理解错了实验要求的意思)
解决这个问题的难点在于,如何把给定两点间的最长路径找出来。这里我用了dfs深度优先搜索算法(ChatGPT提供),返回除去起点和终点的arraylist。在poem方法里也是定义变量为arraylist,先将input作为数组放入arraylist中,然后将两点之间的最长路径插入这个arraylist中,逐两个单词去寻找最长路径,直到最后一个单词。最后返回arraylist的tostring(用空格隔开)。

public ArrayList<String> path(String source, String target) {
	ArrayList<String> result = new ArrayList<>();
	Set<String> visited = new HashSet<>();
	visited.add(source);
	dfs(source, target, new ArrayList<>(), visited, result);
	result.remove(source);
	result.remove(target);
	return result;
}
private void dfs(String current, String target, List<String> path, Set<String> visited, List<String> result) {
	path.add(current);
	if (current.equals(target)) {
		// 找到了一条新路径,更新结果数组
		if (path.size() > result.size()) {
			result.clear();
			result.addAll(path);
		}
		return;
	}
	for (String neighbor : graph.targets(current).keySet()) {
		if (visited.contains(neighbor)) {
			continue;
		}
		visited.add(neighbor);
		dfs(neighbor, target, path, visited, result);
		visited.remove(neighbor);
	}
	path.remove(path.size() - 1);
}
ArrayList<String> words = new ArrayList<>(Arrays.asList(word));
for (int i = 0; i < words.size() - 1; i++) {
	if (graph.vertices().contains(words.get(i + 1).toLowerCase())) {
		ArrayList<String> path = path(words.get(i).toLowerCase(), words.get(i + 1).toLowerCase());
		words.addAll(i + 1, path);
		i += path.size();
	}
}

接下来就是编写测试用例了。测试用例里需要准备各种各样的不同情况。例如需要测试空输入、一行输入、多行输入等情况。

在P1结束前最后还需要做一个代码覆盖率测试。最后测试结果除了一个方法外其他方法都测试到了。你猜怎么着——这个唯一没有被测试到的方法竟然是poetwalk里的main方法。这让我怎么测试啊。

再度总结

P1的主要难点在于看懂MIT的翻译(面向MIT编程),这个翻译实在是太怪了,看了好久才大概理解了它的意思。关键在于美国的这些语言不像我们的这般严谨,而是夹杂着许多幽默风趣的用语(也许是为了与学生拉近感情)。这样子本来没问题,但是一旦翻译过来就会变得非常奇怪,导致我根本搞不懂有些话到底是实验要求还是抒发感情的幽默用语。很苦恼啊。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值