任务链接:http://coursera.cs.princeton.edu/algs4/assignments/boggle.html

这次任务给的需要实现的方法很少,完成本次任务关键在于理清思路,需要实现较多的私有方法。

需要自己设计单词树,将单词树中每个字符节点定义为一个类。

private static class Node  // 字典中节点类{private boolean isWord;  // 到达该节点是否为单词标志位private Node[] next = new Node[R];  // 该节点的后继节点}

该单词节点类有一个标志位,表示从头节点到该节点所构成字符序列为一个单词。next数组表示该字符之后接下来可能出现的26个字符节点类。

另外设计一个存储相邻节点下标的类,用于存储该节点在面板中相邻的8个(最多)方向的字符的下标,并用n标记真实数组的长度

private static class Adjacent  // 游戏面板相邻节点类{private int n = 0;  // 相邻节点数组长度private int[] neighbor = new int[8]; // 相邻节点}

设计步骤:

首先,我们需要为给定的单词词集设计成单词树。

然后对面板的字符采用DFS方法进行组成字符序列查找单词树。当查到单词树的叶子节点时就停止本次查找。和之前的DFS不同的时,在对mark数组进行处理的时候,在退出递归查找之前需将给位置mark设置为false,以便别的单词序列能包含该字符。

其中为了节省时间,需提前计算好每个位置上的字符相邻字符的下标。即利用上面的Adjacent类。

import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.SET;
import edu.princeton.cs.algs4.StdOut;public class BoggleSolver
{private static final int R = 26;  // A-Zprivate boolean[][] marked;  // 游戏面板遍历标志位private char[][] boardChar;  // 游戏面板存放字符private Adjacent[] adjacents;  // 相邻节点数组private int row;  // 行private int col;  // 列private Node root;  // 字典根节点private static class Node  // 字典中节点类{private boolean isWord;  // 到达该节点是否为单词标志位private Node[] next = new Node[R];  // 该节点的后继节点}private static class Adjacent  // 游戏面板相邻节点类{private int n = 0;  // 相邻节点数组长度private int[] neighbor = new int[8]; // 相邻节点}// 使用给定的字符串数组作为字典初始化数据结构。// (你可以假设字典中的每个单词只包含大写字母A到Z)。public BoggleSolver(String[] dictionary){if (dictionary == null)throw new java.lang.IllegalArgumentException("the string[] is null");// 依次添加进字典中for (int i = 0; i < dictionary.length; i++)addToDictionary(dictionary[i]);}// 将单词插入字典中private void addToDictionary(String word){if (word == null) throw new java.lang.IllegalArgumentException("the string is null");root = add(root, word, 0);}// 对单词的字符进行操作private Node add(Node x, String word, int d){if (x == null) x = new Node();if (d == word.length())   // 到达单词结尾时,在对应的字符节点处设置为是单词标志x.isWord = true;else {char c = word.charAt(d);x.next[c - 'A'] = add(x.next[c - 'A'], word, d + 1);}return x;}// 判断字典中是否有该单词private boolean contains(String word){if (word == null)throw new java.lang.IllegalArgumentException("the word is null");Node x = get(root, word, 0);if (x == null) return false;elsereturn x.isWord;}// 以递归方式查找单词// 当对应位置无字符时返回null,否则返回该字符节点private Node get(Node node, String word, int d){if (node == null) // 字典中该位置没有字符存储return null;else {if (d < word.length()) {  // 递归查找下一节点char c = word.charAt(d);return get(node.next[c - 'A'], word, d + 1);}elsereturn node;}}// 返回给定的BogGrand板中所有有效单词的集合,作为一个迭代。public Iterable<String> getAllValidWords(BoggleBoard board){if (board == null) throw new java.lang.IllegalArgumentException("the board is null");// 减少内存if (row != board.rows() || col != board.cols()) {row = board.rows(); // 行col = board.cols(); // 列marked = new boolean[row][col]; // 面板标志位boardChar = new char[row][col]; // 面板字符位computeAdj(); // 计算相邻位置的下标}for (int i = 0; i < row; i++)  // 行for (int j = 0; j < col; j++) // 列boardChar[i][j] = board.getLetter(i, j); // 拷贝字母SET<String> words = DFS();return words;}// 计算相邻位置的下标private void computeAdj(){adjacents = new Adjacent[row * col];  // 相邻节点数组for (int i = 0; i < row; i++) {  // 行for (int j = 0; j < col; j++) {  // 列int index = i * col + j;adjacents[index] = new Adjacent(); // adj[index].neineighbor[k]表示 临近节点的下标if (i > 0) // 上 {// 左上if (j > 0)  adjacents[index].neighbor[adjacents[index].n++] = (i - 1) * col + j - 1;// 正上adjacents[index].neighbor[adjacents[index].n++] = (i - 1) * col + j;// 右上if (j < col -1) adjacents[index].neighbor[adjacents[index].n++] = (i - 1) * col + j + 1;}// 右if (j < col -1) adjacents[index].neighbor[adjacents[index].n++] = i * col + j + 1;if (i < row -1) // 下 {// 右下if (j < col -1) {adjacents[index].neighbor[adjacents[index].n++] = (i + 1) * col + j + 1;}// 正下adjacents[index].neighbor[adjacents[index].n++] = (i + 1) * col + j;// 左下if (j > 0) adjacents[index].neighbor[adjacents[index].n++] = (i + 1) * col + j - 1;}// 左if (j > 0) adjacents[index].neighbor[adjacents[index].n++] = i * col + j - 1;}}}// 深度优先遍历搜索private SET<String> DFS(){SET<String> words = new SET<>(); // 用于存放找到的单词for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) DFS(i, j, new StringBuilder(), words, root);return words;}// 深度优先搜索面板private void DFS(int indexi, int indexj, StringBuilder pre, SET<String> words, Node node){char c = boardChar[indexi][indexj];Node next = node.next[c - 'A'];if (c == 'Q' && next != null) next = next.next['U' - 'A'];if (next == null)return;if (c == 'Q') // QU问题pre.append("QU");elsepre.append(c);String string = pre.toString();if (pre.length() > 2 && next.isWord) // 是单词words.add(string);marked[indexi][indexj] = true;for (int i = 0; i < adjacents[indexi * col + indexj].n; i++) {int indexk = adjacents[indexi * col + indexj].neighbor[i]; //相邻节点的下标int indexrow = indexk / col; // 该下标的节点所在行int indexcol = indexk % col; // 该下标节点所在的列if (!marked[indexrow][indexcol]) DFS(indexrow, indexcol, new StringBuilder(pre), words, next);}marked[indexi][indexj] = false; // 以便别的单词能继续查找}// 如果它在字典中返回给定单词的分数,否则为零。// (你可以假设这个词只包含大写字母A到Z)。public int scoreOf(String word){if (word == null) throw new java.lang.IllegalArgumentException("the word is null");if (!contains(word)) return 0;if (word.length() <= 2) return 0;else if (word.length() <= 4)return 1;else if (word.length() == 5) return 2;else if (word.length() == 6) return 3;else if (word.length() == 7) return 5;else return 11;             }public static void main(String[] args) {In in = new In(args[0]);String[] dictionary = in.readAllStrings();BoggleSolver solver = new BoggleSolver(dictionary);BoggleBoard board = new BoggleBoard(args[1]);int score = 0;for (String word : solver.getAllValidWords(board)) {StdOut.println(word);score += solver.scoreOf(word);}StdOut.println("Score = " + score);}
}

Coursera普林斯顿大学算法下Week4:Boggle 拼字游戏相关推荐

  1. 拼字游戏 html5,拼字游戏攻略

    拼字游戏是一款趣味性十足的游戏方式会让大家快乐的游戏.游戏十分益智.这款游戏风格独特,画面精美好看,音效逼真动听,操作简单易上手.相信你一定会喜欢的,如果你喜欢的话就加入我们吧,以下是关于这个游戏的一 ...

  2. FB社交游戏2011盘点:街机游戏、拼字游戏、博彩游戏排行前三

    2011年,Facebook上的游戏类型区域多样化,诸如寻宝游戏.赛车游戏.和即时多人战略游戏等游戏类型纷纷登陆Facebook.那么,今年推出的游戏中哪些类型的表现更好呢?通过AppData的数据, ...

  3. 普林斯顿大学算法第一周个人总结1

    来自普林斯顿大学 的 Coursera 课程<算法,第一部分> ,课程地址:https://www.coursera.org/course/algs4partI 第一周的内容是 Union ...

  4. 普林斯顿大学算法课 Algorithm Part I Week 3 自我总结

    要熟练掌握比较器Comparator public final Comparator<T> MY_COMPARATOR = new myComparator(); //定义比较器 .... ...

  5. 普林斯顿大学算法公开课笔记

    第一章 Union-Find 01 Dynamic connectivity (动态连接性问题即 the model of union find 并查集模型) 问题: a set of N objec ...

  6. 动态规划解决贴纸拼字游戏

    文章目录 题目描述 分析 题目描述 我们给出了 N 种不同类型的贴纸.每个贴纸上都有一个小写的英文单词. 你希望从自己的贴纸集合中裁剪单个字母并重新排列它们,从而拼写出给定的目标字符串 target. ...

  7. python之穿越火线游戏代码_Python实现拼字游戏与代码重构

    有位文豪说得好:"看一个作家的水平,不是看他发表了多少文字,而要看他的废纸篓里扔掉了多少." 我觉得同样的理论适用于编程.好的程序员,他们删掉的代码,比留下来的还要多很多.如果你看 ...

  8. C语言算法之:猜字游戏

    专注职业教育&教研设备+自媒体链接+智慧投资. 只要肯花时间,一定会有所成长. 学技术,重在日拱一卒.一点一滴的积累. 今天一起分析C语言的算法之10:猜字游戏. 算法题目: 猜1个一百以内的 ...

  9. 3目标检测的准确率_吊打YOLOv3!普林斯顿大学提出:CornerNetLite,基于关键点的实时且精度高的目标检测算法,已开源!...

    点击上方"CVer",选择"星标"和"置顶" 重磅干货,第一时间送达 前戏 最近目标检测方向,出了很多很棒的paper,CVer也立即跟进报 ...

最新文章

  1. HDU 3826 Squarefree number:题目解答源码
  2. ffmpeg处理视频命令
  3. ThinkPHP add、save无法添加、修改不起作用
  4. ttl接地是高电平还是低电平_功放技术参数1——高电平
  5. 【LCT】历史(P4338)
  6. Java中List、Map、Set三个接口,存取元素时,各有什么特点?
  7. 第一次使用mysql_第一次使用mysql,求帮忙
  8. iconv 判断字符编码_GBK 和 UTF8编码
  9. 心脏为什么长在左边?原来是因为这个消失的器官
  10. python怎么导入数据集keras_python – 如何为Keras准备数据集?
  11. ajax 连接java,如何使用Ajax连接到Java servlets?
  12. WCF分布式开发常见错误(3):客户端调用服务出错
  13. PyTorch:卷积/padding/pooling api
  14. JVM 堆内存设置 -Xmx -Xms
  15. python PDF文件转JPG
  16. fiddler软件抓包工具超详细配置方法
  17. nginx resolver失败
  18. 小白快速体验之爬虫抓取新浪热搜
  19. 新福克斯刷隐藏功能简明教程(转)
  20. 300M宽带网速只有16M?下载速度达到多少才算正常?

热门文章

  1. 推荐几款实用的内网穿透工具
  2. php中mysql_assoc,在PHP中使用mysql_fetch_assoc时出现警告
  3. jsp提交判空/jsp重置
  4. 如何运营出一个有吸引力的微信公众号?
  5. winPE下安装系统ghost恢复系统图文详细教程
  6. 设置屏幕常亮 switch
  7. 穿越功耗墙,从哪些方面提升性能?
  8. Lambda 表达式详解
  9. 社群空间站一键发布微信群精品优质社群的搜索和发布平台源码
  10. Windows AD域功能介绍、Windows AD域方案介绍