• 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.之后再来写。

  • 相关阅读:
    POJ2503——Babelfish
    深入理解Spring AOP之二代理对象生成
    怎样让索引仅仅能被一个SQL使用
    Linux下改动Oracle数据库字符集命令
    LeetCode15:3Sum
    【C语言】编写函数实现库函数atoi,把字符串转换成整形
    Scala入门到精通——第二十二节 高级类型 (一)
    J2SE核心开发实战(一)——认识J2SE
    A glance on VDBI
    zookeeper 配置文件说明(zoo.cfg)
  • 原文地址:https://www.cnblogs.com/huipengly/p/9884668.html
Copyright © 2020-2023  润新知