1.串的快速检索 给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。 在这道题中,我们可以用数组枚举,用哈希,用字典树,先把熟词建一棵树,然后读入文章进行比较,这种方法效率是比较高的。 2.串排序 给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序从小到大输出用字典树进行排序,采用数组的方式创建字典树,这棵树的每个结点的所有儿子很显然地按照其字母大小排序。对这棵树进行先序遍历即可。 3.最长公共前缀 对所有串建立字典树,对于两个串的最长公共前缀的长度即他们所在的结点的公共祖先个数,于是,问题就转化为当时公共祖先问题。
public class TrieTree {
private Node root = new Node();
public TrieTree() {
}
public void add(String s) {
Node p = root;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (!p.map.containsKey(c)) {
p.map.put(c, new Node());
}
p = p.map.get(c);
}
p.isleaf = true;
}
public boolean contains(String s) {
Node p = root;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (!p.map.containsKey(c)) {
return false;
}
p = p.map.get(c);
}
return p.isleaf;
}
/**
* 最长公共前缀
*/
public String maxlengthcommonstr() {
StringBuilder sb = new StringBuilder();
Node p = root;
while (!p.isleaf && p.map.size() == 1) {
Set<Character> set = p.map.keySet();
for (char c:set) {
sb.append(c);
p = p.map.get(c);
}
}
return sb.toString();
}
/**
* 先序遍历字典树
*/
public void traverse() {
Node p = root;
Stack<Map.Entry<Character, Node>> stack = new Stack<>();
traverse(p, stack);
}
/**
* 先序遍历,此时一般节点的map用的是TreeMap
* 用来作为每个字符串排序
*/
public static void traverse(Node node, Stack<Map.Entry<Character, Node>> stack) {
if (!node.map.entrySet().isEmpty()) {
for (Map.Entry<Character, Node> entry:node.map.entrySet()) {
stack.push(entry);
traverse(entry.getValue(), stack);
stack.pop();
}
} else {
stack.forEach((Map.Entry<Character, Node> entity)->{
Character key = entity.getKey();
System.out.printf("%c", key);
});
System.out.println();
}
}
public static class Node {
/**
* 根据是否要对字符串进行排序,切换使用TreeMap和HashMap
*/
Map<Character, Node> map = new TreeMap();
boolean isleaf = false;
}
public static void main(String[] args) {
TrieTree trieTree = new TrieTree();
String[] ss = {"HelloWorld", "HelloABC", "HelloWuliyu", "Hello123"};
for (int i = 0; i < ss.length; i++) {
trieTree.add(ss[i]);
}
trieTree.traverse();
}
}