要求当用户在浏览器的地址栏输入地址时,浏览器能够根据用户输入的历史记录对用户现在的输入进行匹配,提示用户可能要输入的字符。大概意思就是要实现和现在浏览器差不多的效果,比如用户之前输入过aaa,abcd,abcc(简化以下,不考虑前缀”www.”和后缀”.com”),当用户再次在浏览器地址栏输入a时,系统能够提示aaa,aaaa,abcd,abcc。输入ab时,系统能够提示abcd,abcc。
思路:感觉可以用树的结构解决该问题,解决过程如下:
1.数据结构选择
用户输入aaa,aaaa,abcd,abcc,后,内部存储结构为:
树的数据结构为:
class Tree { Tree tParent; char val; boolean flag; List<Tree> children; Tree(Tree p, char c, boolean b) { tParent = p; val = c; flag = b; children = new ArrayList<Tree>(); } }
其中flag用于表明是否至此为止可得到一条路径。
2.建树过程。
用户输入aaa,aaaa,abcd,abcc,后,树的变化过程如下图所示:
图V即为存储历史数据aaa&aaaa&abcd&abcc后的最终结果,其中黄色节点即表示flag=true,表明输入的历史数据中存有一条历史数据到黄色节点为止。
3.搜索过程。
以用户输入aa&ac为例。输入aa后,系统在树中找到符号条件的点(即图中红色节点)。以该节点为根遍历,以黄色的点为结尾,即可得到a&aa。加上前缀,即得到最终结果:aaa、aaaa。输入ac后,无法在树中找到ac,因此无提示
4.CODE:
import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; import java.util.Queue; class Tree { Tree tParent; char val; boolean flag; List<Tree> children; Tree(Tree p, char c, boolean b) { tParent = p; val = c; flag = b; children = new ArrayList<Tree>(); } } public class Solution { /** * 向root中插入节点,返回插入的节点。插入过程中注意flag的设置 * * @param root * @param c * @param b * @return */ public static Tree insert(Tree root, char c, boolean b) { Tree node = new Tree(root, c, b); if (!isContain(root.children, node)) { root.children.add(node); } else { for (Tree temp : root.children) if (temp.val == node.val) { if (b == true) temp.flag = b; return temp; } } return node; } /** * 判断children中是否已存在node * * @param children * @param node * @return */ public static boolean isContain(List<Tree> children, Tree node) { for (Tree temp : children) { if (temp.val == node.val) return true; } return false; } /** * 打印以node为根节点的路径 * * @param node */ public static void printPath(Tree node) { Queue<Tree> queue = new ArrayDeque<Tree>(); Tree temp = new Tree(null, '.', false); queue.add(node); while (queue.size() != 0) { temp = queue.poll(); if (temp.flag == true) { Tree ori = new Tree(null, ',', false); ori = temp; String strTemp = ""; while (temp.tParent != null) { strTemp += temp.val; temp = temp.tParent; } for (int i = strTemp.length() - 1; i >= 0; --i) System.out.print(strTemp.charAt(i)); System.out.println(); temp = ori; } for (Tree t : temp.children) queue.add(t); } } /** * 查找&遍历 * * @param root * @param str */ public static void SendHint(Tree root, String str) { Tree node = searchNode(root, str); if (node == null) { System.out.println("No Hint"); return; } printPath(node); } /** * 根据输入的string在历史树中进行查找,找到符合条件的节点返回(对该节点进行遍历即可得到最终提示) * * @param root * @param str * @return */ public static Tree searchNode(Tree root, String str) { if (str == null || str.length() == 0) return root; for (int i = 0; i < str.length(); ++i) { for (Tree node : root.children) { if (node.val == str.charAt(i)) { return searchNode(node, str.substring(i + 1, str.length())); } } } return null; } public static void main(String[] args) { // TODO Auto-generated method stub Tree origin = new Tree(null, '.', false); Tree root = new Tree(null, '.', false); origin = root; String[] str = { "aaa", "aaaa", "abcd", "abcc", "adbc", "adddd" }; // 建树 for (String temp : str) { for (int i = 0; i < temp.length(); ++i) { root = insert(root, temp.charAt(i), (i == temp.length() - 1)); } root = origin; } // 搜索 SendHint(origin, "ab"); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-12 06:44:12