Programming Assignment 4: Boggle

Programming Assignment 4: Boggle

1. 题目阅读

编写程序去玩Boggle游戏。

Boggle游戏 一个文字游戏,他包含了16个骰子,骰子的每一面都印着一个字母。游戏最初,摇晃16个骰子,并且随机的分配到4*4的托盘中,只有骰子的顶面可以被看到。玩家根据以下规则,使用骰子建立有效的单词来竞争积分。

  • 一个有效的单词必须通过横向,纵向,斜向相连。
  • 一个有效的单词只能使用一个骰子一次。
  • 一个有效的单词至少包括3个字母
  • 一个有效的单词必须在字典中

例子见原网页

评分 | word length | points | | ----------- | ------ | | 0–2 | 0 | | 3–4 | 1 | | 5 | 2 | | 6 | 3 | | 7 | 5 | | 8+ | 11 |

Qu特例 在英语中,字母Q后总跟着u,所以,骰子上使用Qu取代Q,当组成单词时,这两个字母都需要被用到。当评分时,Qu被算作两个字母。

你的任务 编写一个Boggle求解器,使用给定的字典,找到给定Boggle板中所有有效的单词。使用下面的API实现一个不变的数据结构BoggleSolver。

如何搜索、存储板中包含的单词和用来检查的字典的实现由你确定。

板类型 我们为BoggleBoard板提供一个不变的数据结构。他包含了从16个随机的骰子中创建板子,按照英语单词频率、通过一个文件或一个字母数组创建。包含了读取独立字母的方法,一个用来调试的打印board的方法。

性能 处理得当,可以在一秒内得到答案。

2. 问题分析

这个问题可以分为两点,第一是如何获得板中所有可能的字母连接,第二是如何判断字符串是有效的单词。

获得所有字母连接 第一反应是把这个板当作一个无向图,然后从每个字母开始进行深度优先搜索,然后判断。这里我有一个疑惑,就是深度优先搜索能否搜到所有的可能,因为这个方式只会通过一个节点一次。关于这个疑惑,checklist里面有一个剪枝的策略,就是判断当前的字母组合是否为一个有效的单词的prefix,若不是则剪枝。剪枝后,原先走过的点还可以走,只是不能走剪掉的路了。这样就能确保搜到所有的节点组合。

判断字符串是否有效 这里还需要判断prefix,考虑使用一个tst。

具体实现。

构造函数需要使用给定的字典新建一个tst。

分数计算,声明一个长度对应分数的数组,然后查表返回。

实现一个dfs搜索board,dfs返回时将点置为可走,并且参数多一个之前字母组成的string。每次dfs首先判断在字典是否有单词有prefix,然后向八个方向搜索。

第一遍性能太差了。

3. 性能优化

自己实现一个26way-trie.对于prefix判断,不需要像tst一样,返回迭代器,只需要迭代判断字母组合每一位,当未迭代完就有null,则无prefix;当迭代完还有下一位,则一定有符合的单词,也不需要再判断,并且可以判断当前字母组合是否为一个单词

上面的优化还不够。

考虑保留每次搜索prefix到达的node,然后从这个node开始搜索。

这个优化还是不够,还是引入了bug。

20181029 : 暂时不写了。96/100.之后再来写。

posted @ 2018-10-31 17:55  huipengly  阅读(423)  评论(0编辑  收藏  举报