2019独角兽企业重金招聘Python工程师标准>>>
将500W个单词放进一个数据结构进行存储,然后进行快速比对,判断一个单词是不是这个500W单词之中的;来了一个单词前缀,给出500w个单词中有多少个单词是该前缀.
1、这个需求首先需要设计好数据结构,要求快速判断一个单词是否在这500W之中,挨个遍历肯定不是好办法,即便你把他们放在一个数组或者链表里,用多线程分段查找,最好是几次查找就可以知道结果。
我们把所有单词的前缀作为上层,剩下的字符逐级加入到树的下层结构中,并记录树的上层节点的子节点数。这样我们只要判断新单词跟树的上层节点的前缀比对,那么其他不匹配的节点就无需继续遍历,只需要在该节点往下查找后续的字符比对,他的时间复杂度可能就很低了,只需要几次比对就能判断出是否包含该新单词。整个数据结构可以书写如下。
public class DictionaryTree { // 字典树的节点 private class Node { // 是否是单词 private boolean isWord; // 单词计数 private int count; // 字串 private String str; // 子节点 private Map<String, Node> childs; // 父节点 private Node parent; public Node() { childs = new HashMap<String, Node>(); } public Node(boolean isWord, int count, String str) { this(); this.isWord = isWord; this.count = count; this.str = str; } public void addChild(String key, Node node) { childs.put(key, node); node.parent = this; } public void removeChild(String key) { childs.remove(key); } public String toString() { return "str : " + str + ", isWord : " + isWord + ", count : " + count; } } // 字典树根节点 private Node root; public DictionaryTree() { // 初始化root root = new Node(); } // 添加字串 private void addStr(String word, Node node) { // 计数 node.count++; String str = node.str; if (null != str) { // 寻找公共前缀 String commonPrefix = ""; for (int i = 0; i < word.length(); i++) { if (str.length() > i && word.charAt(i) == str.charAt(i)) { commonPrefix += word.charAt(i); } else { break; } } // 找到公共前缀 if (commonPrefix.length() > 0) { if (commonPrefix.length() == str.length() && commonPrefix.length() == word.length()) { // 与之前的词重复 } else if (commonPrefix.length() == str.length() && commonPrefix.length() < word.length()) { // 剩余的串 String wordLeft = word.substring(commonPrefix.length()); // 剩余的串去子节点中继续找 searchChild(wordLeft, node); } else if (commonPrefix.length() < str.length()) { // 节点裂变 Node splitNode = new Node(true, node.count, commonPrefix); // 处理裂变节点的父关系 splitNode.parent = node.parent; splitNode.parent.addChild(commonPrefix, splitNode); node.parent.removeChild(node.str); node.count--; // 节点裂变后的剩余字串 String strLeft = str.substring(commonPrefix.length()); node.str = strLeft; splitNode.addChild(strLeft, node); // 单词裂变后的剩余字串 if (commonPrefix.length() < word.length()) { splitNode.isWord = false; String wordLeft = word.substring(commonPrefix.length()); Node leftNode = new Node(true, 1, wordLeft); splitNode.addChild(wordLeft, leftNode); } } } else { // 没有共同前缀,直接添加节点 Node newNode = new Node(true, 1, word); node.addChild(word, newNode); } } else { // 根结点 if (node.childs.size() > 0) { searchChild(word, node); } else { Node newNode = new Node(true, 1, word); node.addChild(word, newNode); } } } // 在子节点中添加字串 public void searchChild(String wordLeft, Node node) { boolean isFind = false; if (node.childs.size() > 0) { // 遍历孩子 for (String childKey : node.childs.keySet()) { Node childNode = node.childs.get(childKey); // 首字母相同,则在该子节点继续添加字串 if (wordLeft.charAt(0) == childNode.str.charAt(0)) { isFind = true; addStr(wordLeft, childNode); break; } } } // 没有首字母相同的孩子,则将其变为子节点 if (!isFind) { Node newNode = new Node(true, 1, wordLeft); node.addChild(wordLeft, newNode); } } // 添加单词 public void add(String word) { addStr(word, root); } // 在节点中查找字串 private boolean findStr(String word, Node node) { boolean isMatch = true; String wordLeft = word; String str = node.str; if (null != str) { // 字串与单词不匹配 if (word.indexOf(str) != 0) { isMatch = false; } else { // 匹配,则计算剩余单词(从匹配的后一位到最后一位) wordLeft = word.substring(str.length()); } } // 如果匹配 if (isMatch) { // 如果还有剩余单词长度 if (wordLeft.length() > 0) { if (node.childs.size() > 0) { // 遍历孩子继续找 for (String key : node.childs.keySet()) { Node childNode = node.childs.get(key); //递归 boolean isChildFind = findStr(wordLeft, childNode); if (isChildFind) { return true; } } }else { //如果没有子节点了,返回false return false; } } else { // 没有剩余单词长度,说明已经匹配完毕,直接返回节点是否为单词,匹配到即便符合前缀,也不能算单词 return node.isWord; } } return false; } // 查找单词 public boolean find(String word) { return findStr(word, root); } // 统计子节点字串单词数 private int countChildStr(String prefix, Node node) { // 遍历孩子 for (String key : node.childs.keySet()) { Node childNode = node.childs.get(key); // 匹配子节点 int childCount = countStr(prefix, childNode); if (childCount != 0) { return childCount; } } return 0; } // 统计字串单词数 private int countStr(String prefix, Node node) { String str = node.str; // 非根结点 if (null != str) { // 前缀与字串不匹配 if (prefix.indexOf(str) != 0 && str.indexOf(prefix) != 0) { return 0; // 前缀匹配字串,且前缀较短 } else if (str.indexOf(prefix) == 0) { // 找到目标节点,返回单词数 return node.count; // 前缀匹配字串,且字串较短 } else if (prefix.indexOf(str) == 0) { // 剩余字串继续匹配子节点 String prefixLeft = prefix.substring(str.length()); if (prefixLeft.length() > 0) { return countChildStr(prefixLeft, node); } } } else { // 根结点,直接找其子孙 return countChildStr(prefix, node); } return 0; } // 统计前缀单词数 public int count(String prefix) { // 处理特殊情况 if (null == prefix || prefix.trim().isEmpty()) { return root.count; } // 从根结点往下匹配 return countStr(prefix, root); } // 打印节点 private void printNode(Node node, int layer) { // 层级递进 for (int i = 0; i < layer; i++) { System.out.print(" "); } // 打印 System.out.println(node); // 递归打印子节点 for (String str : node.childs.keySet()) { Node child = node.childs.get(str); printNode(child, layer + 1); } } // 打印字典树 public void print() { printNode(root, 0); } }
我们可以先看findStr()方法,主要是递归查找,也就是递归进去几个节点的事情,就OK了.
// 在节点中查找字串 private boolean findStr(String word, Node node) { boolean isMatch = true; String wordLeft = word; String str = node.str; if (null != str) { // 字串与单词不匹配 if (word.indexOf(str) != 0) { isMatch = false; } else { // 匹配,则计算剩余单词(从匹配的后一位到最后一位) wordLeft = word.substring(str.length()); } } // 如果匹配 if (isMatch) { // 如果还有剩余单词长度 if (wordLeft.length() > 0) { if (node.childs.size() > 0) { // 遍历孩子继续找 for (String key : node.childs.keySet()) { Node childNode = node.childs.get(key); //递归 boolean isChildFind = findStr(wordLeft, childNode); if (isChildFind) { return true; } } }else { //如果没有子节点了,返回false return false; } } else { // 没有剩余单词长度,说明已经匹配完毕,直接返回节点是否为单词,匹配到即便符合前缀,也不能算单词 return node.isWord; } } return false; } // 查找单词 public boolean find(String word) { return findStr(word, root); }
第二个需求,来了一个单词前缀,给出500w个单词中有多少个单词是该前缀.
我们来看一下countStr()和countChildStr()两个方法的互相调用,其实就是我只要找到完全匹配子节点的数量就可以得到结果.他的时间复杂度也是非常的低.不需要一个个的去到叶节点去累加,因为上层节点已经有他的全部单词节点节点的数量.(上层节点也可能是一个单词,并非只是叶节点)
// 统计子节点字串单词数 private int countChildStr(String prefix, Node node) { // 遍历孩子 for (String key : node.childs.keySet()) { Node childNode = node.childs.get(key); // 匹配子节点 int childCount = countStr(prefix, childNode); if (childCount != 0) { return childCount; } } return 0; } // 统计字串单词数 private int countStr(String prefix, Node node) { String str = node.str; // 非根结点 if (null != str) { // 前缀与字串不匹配 if (prefix.indexOf(str) != 0 && str.indexOf(prefix) != 0) { return 0; // 前缀匹配字串,且前缀较短 } else if (str.indexOf(prefix) == 0) { // 找到目标节点,返回单词数 return node.count; // 前缀匹配字串,且字串较短 } else if (prefix.indexOf(str) == 0) { // 剩余字串继续匹配子节点 String prefixLeft = prefix.substring(str.length()); if (prefixLeft.length() > 0) { return countChildStr(prefixLeft, node); } } } else { // 根结点,直接找其子孙 return countChildStr(prefix, node); } return 0; } // 统计前缀单词数 public int count(String prefix) { // 处理特殊情况 if (null == prefix || prefix.trim().isEmpty()) { return root.count; } // 从根结点往下匹配 return countStr(prefix, root); }
添加单词也是非常有意思的,来看这么几个方法.当新增加的单词跟已存在的节点单词有相同的前缀时,就要分裂出一个新的前缀节点,并且把该节点本身以及新增加的单词的后续的字符变成两个下一级节点,如果没有就要新增加一个全新的节点.如果已经有前缀可以匹配了,就要匹配下一层的前缀,其他同之前.
// 添加字串 private void addStr(String word, Node node) { // 计数 node.count++; String str = node.str; if (null != str) { // 寻找公共前缀 String commonPrefix = ""; for (int i = 0; i < word.length(); i++) { if (str.length() > i && word.charAt(i) == str.charAt(i)) { commonPrefix += word.charAt(i); } else { break; } } // 找到公共前缀 if (commonPrefix.length() > 0) { if (commonPrefix.length() == str.length() && commonPrefix.length() == word.length()) { // 与之前的词重复 } else if (commonPrefix.length() == str.length() && commonPrefix.length() < word.length()) { // 剩余的串 String wordLeft = word.substring(commonPrefix.length()); // 剩余的串去子节点中继续找 searchChild(wordLeft, node); } else if (commonPrefix.length() < str.length()) { // 节点裂变 Node splitNode = new Node(true, node.count, commonPrefix); // 处理裂变节点的父关系 splitNode.parent = node.parent; splitNode.parent.addChild(commonPrefix, splitNode); node.parent.removeChild(node.str); node.count--; // 节点裂变后的剩余字串 String strLeft = str.substring(commonPrefix.length()); node.str = strLeft; splitNode.addChild(strLeft, node); // 单词裂变后的剩余字串 if (commonPrefix.length() < word.length()) { splitNode.isWord = false; String wordLeft = word.substring(commonPrefix.length()); Node leftNode = new Node(true, 1, wordLeft); splitNode.addChild(wordLeft, leftNode); } } } else { // 没有共同前缀,直接添加节点 Node newNode = new Node(true, 1, word); node.addChild(word, newNode); } } else { // 根结点 if (node.childs.size() > 0) { searchChild(word, node); } else { Node newNode = new Node(true, 1, word); node.addChild(word, newNode); } } } // 在子节点中添加字串 public void searchChild(String wordLeft, Node node) { boolean isFind = false; if (node.childs.size() > 0) { // 遍历孩子 for (String childKey : node.childs.keySet()) { Node childNode = node.childs.get(childKey); // 首字母相同,则在该子节点继续添加字串 if (wordLeft.charAt(0) == childNode.str.charAt(0)) { isFind = true; addStr(wordLeft, childNode); break; } } } // 没有首字母相同的孩子,则将其变为子节点 if (!isFind) { Node newNode = new Node(true, 1, wordLeft); node.addChild(wordLeft, newNode); } } // 添加单词 public void add(String word) { addStr(word, root); }
public void addChild(String key, Node node) { childs.put(key, node); node.parent = this; }
然后我们来一个main()方法进行测试,当然没有加500W个单词那么多,但结果是一样,有兴趣你可以加500W个单词进去
public static void main(String[] args) { DictionaryTree dt = new DictionaryTree(); dt.add("interest"); dt.add("interesting"); dt.add("interested"); dt.add("inside"); dt.add("insert"); dt.add("apple"); dt.add("inter"); dt.add("interesting"); dt.add("aha"); dt.add("fuck"); dt.add("finish"); dt.add("fish"); dt.print(); boolean isFind = dt.find("a"); System.out.println("find a : " + isFind); isFind = dt.find("aha"); System.out.println("find aha : " + isFind); int count = dt.count("inter"); System.out.println("count prefix inter : " + count); }
运行结果:
str : null, isWord : false, count : 12
str : a, isWord : false, count : 2
str : ha, isWord : true, count : 1
str : pple, isWord : true, count : 1
str : in, isWord : false, count : 7
str : ter, isWord : true, count : 5
str : est, isWord : true, count : 4
str : ing, isWord : true, count : 2
str : ed, isWord : true, count : 1
str : s, isWord : false, count : 2
str : ert, isWord : true, count : 1
str : ide, isWord : true, count : 1
str : f, isWord : false, count : 3
str : i, isWord : false, count : 2
str : nish, isWord : true, count : 1
str : sh, isWord : true, count : 1
str : uck, isWord : true, count : 1
find a : false
find aha : true
count prefix inter : 5
实现线程安全性(读写锁实现,初步)
package com.guanjian; /** * Created by Administrator on 2018/10/21. */ import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class DictionaryTree { private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); private Lock readLock = reentrantReadWriteLock.readLock(); private Lock writeLock = reentrantReadWriteLock.writeLock(); // 字典树的节点 private class Node { // 是否是单词 private boolean isWord; // 单词计数 private int count; // 字串 private String str; // 子节点 private Map<String, Node> childs; // 父节点 private Node parent; public Node() { childs = new HashMap<String, Node>(); } public Node(boolean isWord, int count, String str) { this(); this.isWord = isWord; this.count = count; this.str = str; } public void addChild(String key, Node node) { childs.put(key, node); node.parent = this; } public void removeChild(String key) { childs.remove(key); } public String toString() { return "str : " + str + ", isWord : " + isWord + ", count : " + count; } } // 字典树根节点 private Node root; public DictionaryTree() { // 初始化root root = new Node(); } // 添加字串 private void addStr(String word, Node node) { // 计数 node.count++; String str = node.str; if (null != str) { // 寻找公共前缀 String commonPrefix = ""; for (int i = 0; i < word.length(); i++) { if (str.length() > i && word.charAt(i) == str.charAt(i)) { commonPrefix += word.charAt(i); } else { break; } } // 找到公共前缀 if (commonPrefix.length() > 0) { if (commonPrefix.length() == str.length() && commonPrefix.length() == word.length()) { // 与之前的词重复 } else if (commonPrefix.length() == str.length() && commonPrefix.length() < word.length()) { // 剩余的串 String wordLeft = word.substring(commonPrefix.length()); // 剩余的串去子节点中继续找 searchChild(wordLeft, node); } else if (commonPrefix.length() < str.length()) { // 节点裂变 Node splitNode = new Node(true, node.count, commonPrefix); // 处理裂变节点的父关系 splitNode.parent = node.parent; splitNode.parent.addChild(commonPrefix, splitNode); node.parent.removeChild(node.str); node.count--; // 节点裂变后的剩余字串 String strLeft = str.substring(commonPrefix.length()); node.str = strLeft; splitNode.addChild(strLeft, node); // 单词裂变后的剩余字串 if (commonPrefix.length() < word.length()) { splitNode.isWord = false; String wordLeft = word.substring(commonPrefix.length()); Node leftNode = new Node(true, 1, wordLeft); splitNode.addChild(wordLeft, leftNode); } } } else { // 没有共同前缀,直接添加节点 Node newNode = new Node(true, 1, word); node.addChild(word, newNode); } } else { // 根结点 if (node.childs.size() > 0) { searchChild(word, node); } else { Node newNode = new Node(true, 1, word); node.addChild(word, newNode); } } } // 在子节点中添加字串 public void searchChild(String wordLeft, Node node) { boolean isFind = false; if (node.childs.size() > 0) { // 遍历孩子 for (String childKey : node.childs.keySet()) { Node childNode = node.childs.get(childKey); // 首字母相同,则在该子节点继续添加字串 if (wordLeft.charAt(0) == childNode.str.charAt(0)) { isFind = true; addStr(wordLeft, childNode); break; } } } // 没有首字母相同的孩子,则将其变为子节点 if (!isFind) { Node newNode = new Node(true, 1, wordLeft); node.addChild(wordLeft, newNode); } } // 添加单词 public void add(String word) { try { writeLock.lock(); addStr(word, root); }finally { writeLock.unlock(); } } // 在节点中查找字串 private boolean findStr(String word, Node node) { boolean isMatch = true; String wordLeft = word; String str = node.str; if (null != str) { // 字串与单词不匹配 if (word.indexOf(str) != 0) { isMatch = false; } else { // 匹配,则计算剩余单词(从匹配的后一位到最后一位) wordLeft = word.substring(str.length()); } } // 如果匹配 if (isMatch) { // 如果还有剩余单词长度 if (wordLeft.length() > 0) { if (node.childs.size() > 0) { // 遍历孩子继续找 for (String key : node.childs.keySet()) { Node childNode = node.childs.get(key); //递归 boolean isChildFind = findStr(wordLeft, childNode); if (isChildFind) { return true; } } }else { //如果没有子节点了,返回false return false; } } else { // 没有剩余单词长度,说明已经匹配完毕,直接返回节点是否为单词,匹配到即便符合前缀,也不能算单词 return node.isWord; } } return false; } // 查找单词 public boolean find(String word) { try { readLock.lock(); return findStr(word, root); }finally { readLock.unlock(); } } // 统计子节点字串单词数 private int countChildStr(String prefix, Node node) { // 遍历孩子 for (String key : node.childs.keySet()) { Node childNode = node.childs.get(key); // 匹配子节点 int childCount = countStr(prefix, childNode); if (childCount != 0) { return childCount; } } return 0; } // 统计字串单词数 private int countStr(String prefix, Node node) { String str = node.str; // 非根结点 if (null != str) { // 前缀与字串不匹配 if (prefix.indexOf(str) != 0 && str.indexOf(prefix) != 0) { return 0; // 前缀匹配字串,且前缀较短 } else if (str.indexOf(prefix) == 0) { // 找到目标节点,返回单词数 return node.count; // 前缀匹配字串,且字串较短 } else if (prefix.indexOf(str) == 0) { // 剩余字串继续匹配子节点 String prefixLeft = prefix.substring(str.length()); if (prefixLeft.length() > 0) { return countChildStr(prefixLeft, node); } } } else { // 根结点,直接找其子孙 return countChildStr(prefix, node); } return 0; } // 统计前缀单词数 public int count(String prefix) { // 处理特殊情况 try { readLock.lock(); if (null == prefix || prefix.trim().isEmpty()) { return root.count; } // 从根结点往下匹配 return countStr(prefix, root); }finally { readLock.unlock(); } } // 打印节点 private void printNode(Node node, int layer) { // 层级递进 for (int i = 0; i < layer; i++) { System.out.print(" "); } // 打印 System.out.println(node); // 递归打印子节点 for (String str : node.childs.keySet()) { Node child = node.childs.get(str); printNode(child, layer + 1); } } // 打印字典树 public void print() { try { readLock.lock(); printNode(root, 0); }finally { readLock.unlock(); } } public static String getRandomString(int length) { Random random=new Random(); StringBuffer sb=new StringBuffer(); //循环length次 for(int i = 0; i < length; i++){ //产生0-2个随机数,既与a-z,A-Z,0-9三种可能 // int number=random.nextInt(3); int number = 1; long result = 0L; switch(number){ //如果number产生的是数字0; case 0: //产生A-Z的ASCII码 result = Math.round(Math.random()*25+65); //将ASCII码转换成字符 sb.append(String.valueOf((char)result)); break; case 1: //产生a-z的ASCII码 result=Math.round(Math.random()*25+97); sb.append(String.valueOf((char)result)); break; case 2: //产生0-9的数字 sb.append(String.valueOf (new Random().nextInt(10))); break; } } return sb.toString(); } public static void main(String[] args) throws InterruptedException { DictionaryTree dt = new DictionaryTree(); CountDownLatch latch = new CountDownLatch(500); Runnable task = new Runnable() { @Override public void run() { dt.add(getRandomString(10)); latch.countDown(); } }; ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2); for (int i = 0;i < 500;i++) { es.submit(task); } latch.await(); // dt.add("interest"); // dt.add("interesting"); // dt.add("interested"); // dt.add("inside"); // dt.add("insert"); // dt.add("apple"); // dt.add("inter"); // dt.add("interesting"); // dt.add("aha"); // dt.add("fuck"); // dt.add("finish"); // dt.add("fish"); dt.print(); boolean isFind = dt.find("a"); System.out.println("find a : " + isFind); isFind = dt.find("aha"); System.out.println("find aha : " + isFind); int count = dt.count("inter"); System.out.println("count prefix inter : " + count); es.shutdown(); } }
运行结果:
str : null, isWord : false, count : 500
str : a, isWord : false, count : 13
str : aynktxfyv, isWord : true, count : 1
str : qsmxpqlhe, isWord : true, count : 1
str : jvtrvhvlp, isWord : true, count : 1
str : dfakhoyje, isWord : true, count : 1
str : myclcdtmm, isWord : true, count : 1
str : cdpenahjw, isWord : true, count : 1
str : fvxoyszdo, isWord : true, count : 1
str : giobhpfeu, isWord : true, count : 1
str : i, isWord : false, count : 2
str : xaakwfbn, isWord : true, count : 1
str : goeeixla, isWord : true, count : 1
str : vthbspcbw, isWord : true, count : 1
str : stmrgrokg, isWord : true, count : 1
str : tstmujfvm, isWord : true, count : 1
str : b, isWord : false, count : 18
str : ahckiaakm, isWord : true, count : 1
str : ibkxlklnp, isWord : true, count : 1
str : syclxybky, isWord : true, count : 1
str : qustarhze, isWord : true, count : 1
str : u, isWord : false, count : 3
str : ohlifgck, isWord : true, count : 1
str : lopecahh, isWord : true, count : 1
str : khclgcyd, isWord : true, count : 1
str : ktybpnhgj, isWord : true, count : 1
str : w, isWord : false, count : 2
str : xogivfbc, isWord : true, count : 1
str : jjdmtiel, isWord : true, count : 1
str : x, isWord : false, count : 3
str : qimqqitp, isWord : true, count : 1
str : giwcjqvv, isWord : true, count : 1
str : tpmunncg, isWord : true, count : 1
str : npixbfxgq, isWord : true, count : 1
str : j, isWord : false, count : 2
str : ktvhgytz, isWord : true, count : 1
str : jcxrihjw, isWord : true, count : 1
str : lcsrejxcj, isWord : true, count : 1
str : ezxizwqnx, isWord : true, count : 1
str : c, isWord : false, count : 23
str : bvbvpncmi, isWord : true, count : 1
str : a, isWord : false, count : 2
str : ohbsqhyv, isWord : true, count : 1
str : pgrhuhvj, isWord : true, count : 1
str : fqdmrupqi, isWord : true, count : 1
str : xzkqsrfnl, isWord : true, count : 1
str : qnjvgwlqm, isWord : true, count : 1
str : ylxqipkii, isWord : true, count : 1
str : vxmxaogax, isWord : true, count : 1
str : o, isWord : false, count : 4
str : adtoabkk, isWord : true, count : 1
str : evgmvyox, isWord : true, count : 1
str : obippxob, isWord : true, count : 1
str : wmkmtjln, isWord : true, count : 1
str : myxiuxpse, isWord : true, count : 1
str : jwyypaxpj, isWord : true, count : 1
str : t, isWord : false, count : 2
str : rqbhnnre, isWord : true, count : 1
str : gncvbqsf, isWord : true, count : 1
str : rjfghlovy, isWord : true, count : 1
str : u, isWord : false, count : 2
str : vnzghtcf, isWord : true, count : 1
str : ygicbibt, isWord : true, count : 1
str : w, isWord : false, count : 2
str : ebxnwiba, isWord : true, count : 1
str : jhnsjjfu, isWord : true, count : 1
str : z, isWord : false, count : 2
str : gcxchyhj, isWord : true, count : 1
str : fmgotnym, isWord : true, count : 1
str : d, isWord : false, count : 20
str : b, isWord : false, count : 2
str : isoprvlr, isWord : true, count : 1
str : kwwchnhv, isWord : true, count : 1
str : g, isWord : false, count : 2
str : ubhtbbdb, isWord : true, count : 1
str : thnfdskg, isWord : true, count : 1
str : thgudyfqy, isWord : true, count : 1
str : nxfvflgyf, isWord : true, count : 1
str : i, isWord : false, count : 2
str : hhfflsmk, isWord : true, count : 1
str : botkntno, isWord : true, count : 1
str : k, isWord : false, count : 2
str : wwetdhxd, isWord : true, count : 1
str : kmksjtvo, isWord : true, count : 1
str : ahfxtzfwy, isWord : true, count : 1
str : ennqllhgu, isWord : true, count : 1
str : ukxjneotd, isWord : true, count : 1
str : o, isWord : false, count : 2
str : pfwgcijy, isWord : true, count : 1
str : buchntfb, isWord : true, count : 1
str : cxdouqbfr, isWord : true, count : 1
str : wlfjthkap, isWord : true, count : 1
str : xyxywylpf, isWord : true, count : 1
str : hzgvpnafs, isWord : true, count : 1
str : zjkpjzttb, isWord : true, count : 1
str : e, isWord : false, count : 20
str : b, isWord : false, count : 2
str : uctinobl, isWord : true, count : 1
str : bbqjgdup, isWord : true, count : 1
str : fbwjnhbej, isWord : true, count : 1
str : i, isWord : false, count : 2
str : rvpojxdf, isWord : true, count : 1
str : gsydkjyn, isWord : true, count : 1
str : j, isWord : false, count : 2
str : usflntug, isWord : true, count : 1
str : fkqfyhyb, isWord : true, count : 1
str : omdkokrvr, isWord : true, count : 1
str : qhvvhucmb, isWord : true, count : 1
str : drqpbvhlx, isWord : true, count : 1
str : vvtrgqsdy, isWord : true, count : 1
str : lwqlxzpwg, isWord : true, count : 1
str : sifbolcpi, isWord : true, count : 1
str : tragbqswl, isWord : true, count : 1
str : awfsciltt, isWord : true, count : 1
str : w, isWord : false, count : 3
str : icvimuaz, isWord : true, count : 1
str : nxluecgg, isWord : true, count : 1
str : tdqioyrz, isWord : true, count : 1
str : hgnbncypo, isWord : true, count : 1
str : untsoedek, isWord : true, count : 1
str : f, isWord : false, count : 19
str : ffzeobwsr, isWord : true, count : 1
str : s, isWord : false, count : 3
str : dclynbdk, isWord : true, count : 1
str : gmpwfjrj, isWord : true, count : 1
str : ewuqujtw, isWord : true, count : 1
str : mfrlmqmfr, isWord : true, count : 1
str : d, isWord : false, count : 6
str : nqrngqrb, isWord : true, count : 1
str : gfyoguqf, isWord : true, count : 1
str : esyjhfzm, isWord : true, count : 1
str : pejvnpqc, isWord : true, count : 1
str : qkgwhdjm, isWord : true, count : 1
str : mmyrwluh, isWord : true, count : 1
str : bkfagjiri, isWord : true, count : 1
str : psplkjufd, isWord : true, count : 1
str : h, isWord : false, count : 2
str : wutdthld, isWord : true, count : 1
str : dwpjrjbw, isWord : true, count : 1
str : k, isWord : false, count : 2
str : mhgksicu, isWord : true, count : 1
str : wcaxwdnq, isWord : true, count : 1
str : nxuyasjgx, isWord : true, count : 1
str : gewomfbwu, isWord : true, count : 1
str : g, isWord : false, count : 23
str : i, isWord : false, count : 2
str : zjjsubas, isWord : true, count : 1
str : rbcgawsc, isWord : true, count : 1
str : geyfehanp, isWord : true, count : 1
str : j, isWord : false, count : 2
str : gvitwrvd, isWord : true, count : 1
str : amfrozmf, isWord : true, count : 1
str : ssqfbuwbv, isWord : true, count : 1
str : djyvjlrsi, isWord : true, count : 1
str : qvvpdvicc, isWord : true, count : 1
str : lugpxdvej, isWord : true, count : 1
str : fuaxzbyhx, isWord : true, count : 1
str : o, isWord : false, count : 2
str : pjpwkbzh, isWord : true, count : 1
str : ncrwrpho, isWord : true, count : 1
str : prardfgdn, isWord : true, count : 1
str : vcnplwbie, isWord : true, count : 1
str : u, isWord : false, count : 2
str : rzmconay, isWord : true, count : 1
str : esvrfjjv, isWord : true, count : 1
str : kjhyxrrwn, isWord : true, count : 1
str : y, isWord : false, count : 2
str : tidbmpvw, isWord : true, count : 1
str : bpbgagsp, isWord : true, count : 1
str : z, isWord : false, count : 3
str : aeirvyss, isWord : true, count : 1
str : hhkvdvtj, isWord : true, count : 1
str : fvkniezk, isWord : true, count : 1
str : xsqsdhnks, isWord : true, count : 1
str : h, isWord : false, count : 22
str : a, isWord : false, count : 2
str : ghnrudof, isWord : true, count : 1
str : ckkpnlwh, isWord : true, count : 1
str : c, isWord : false, count : 2
str : bgcieeix, isWord : true, count : 1
str : uinorkfm, isWord : true, count : 1
str : d, isWord : false, count : 2
str : cpsughmq, isWord : true, count : 1
str : kmftctvq, isWord : true, count : 1
str : g, isWord : false, count : 2
str : begltzfb, isWord : true, count : 1
str : cmrqgjsj, isWord : true, count : 1
str : j, isWord : false, count : 2
str : wcbqscvq, isWord : true, count : 1
str : hknrmaop, isWord : true, count : 1
str : nxpdvqwcp, isWord : true, count : 1
str : l, isWord : false, count : 2
str : qsxomrcy, isWord : true, count : 1
str : fnjeyout, isWord : true, count : 1
str : xkvtoggor, isWord : true, count : 1
str : hehvmiobd, isWord : true, count : 1
str : s, isWord : false, count : 2
str : ljnwwidx, isWord : true, count : 1
str : nygyfssr, isWord : true, count : 1
str : v, isWord : false, count : 2
str : jytrtose, isWord : true, count : 1
str : encidcbk, isWord : true, count : 1
str : yxwenwbjo, isWord : true, count : 1
str : ie, isWord : false, count : 2
str : ndcsikr, isWord : true, count : 1
str : pkczlwa, isWord : true, count : 1
str : i, isWord : false, count : 21
str : zxtdgcsug, isWord : true, count : 1
str : kgdvcgjwa, isWord : true, count : 1
str : goimnjuxe, isWord : true, count : 1
str : d, isWord : false, count : 2
str : vsnbmygo, isWord : true, count : 1
str : nellduoq, isWord : true, count : 1
str : vsmnbrczt, isWord : true, count : 1
str : ibeuypnkt, isWord : true, count : 1
str : l, isWord : false, count : 2
str : lskozfen, isWord : true, count : 1
str : edguybhq, isWord : true, count : 1
str : ouflycyoe, isWord : true, count : 1
str : ftoyvxhao, isWord : true, count : 1
str : eistonoes, isWord : true, count : 1
str : q, isWord : false, count : 2
str : wdhyditq, isWord : true, count : 1
str : fbfrhzmr, isWord : true, count : 1
str : wkmrtnvjg, isWord : true, count : 1
str : s, isWord : false, count : 4
str : finqjpic, isWord : true, count : 1
str : akdlvdvh, isWord : true, count : 1
str : kvnqexnm, isWord : true, count : 1
str : lshsmdxv, isWord : true, count : 1
str : bplhteiyc, isWord : true, count : 1
str : cetvqlbod, isWord : true, count : 1
str : j, isWord : false, count : 24
str : yqxlnrimk, isWord : true, count : 1
str : dbrgxlhdg, isWord : true, count : 1
str : mtsasvlyp, isWord : true, count : 1
str : c, isWord : false, count : 2
str : nhowgxzt, isWord : true, count : 1
str : jacfwjsi, isWord : true, count : 1
str : uwuhwcaxp, isWord : true, count : 1
str : g, isWord : false, count : 3
str : ijmffwnq, isWord : true, count : 1
str : ceafgjft, isWord : true, count : 1
str : xvxtqffh, isWord : true, count : 1
str : j, isWord : false, count : 2
str : datglbgb, isWord : true, count : 1
str : psofjwbu, isWord : true, count : 1
str : xwnlgjyln, isWord : true, count : 1
str : o, isWord : false, count : 3
str : uicqpgny, isWord : true, count : 1
str : kfrruuhh, isWord : true, count : 1
str : ajdfqsft, isWord : true, count : 1
str : sfsdflxgq, isWord : true, count : 1
str : igfkxtwfm, isWord : true, count : 1
str : ztxjbfluo, isWord : true, count : 1
str : q, isWord : false, count : 2
str : oovyrzen, isWord : true, count : 1
str : nwrsfsjb, isWord : true, count : 1
str : rufxxbisb, isWord : true, count : 1
str : v, isWord : false, count : 2
str : pxkvluon, isWord : true, count : 1
str : vcyiuooi, isWord : true, count : 1
str : fogdyyarp, isWord : true, count : 1
str : k, isWord : false, count : 20
str : uiyhichvr, isWord : true, count : 1
str : mekbpgkkh, isWord : true, count : 1
str : i, isWord : false, count : 2
str : dbahjpps, isWord : true, count : 1
str : slgbmcoy, isWord : true, count : 1
str : recqutazs, isWord : true, count : 1
str : zabvtxmbx, isWord : true, count : 1
str : p, isWord : false, count : 3
str : mgzbigsj, isWord : true, count : 1
str : rsnsneku, isWord : true, count : 1
str : nysqhncd, isWord : true, count : 1
str : yegghtvoe, isWord : true, count : 1
str : ebqtzmlsw, isWord : true, count : 1
str : cw, isWord : false, count : 2
str : yppoojo, isWord : true, count : 1
str : qqiepin, isWord : true, count : 1
str : lnpiibvry, isWord : true, count : 1
str : qkldejdeg, isWord : true, count : 1
str : v, isWord : false, count : 2
str : hcakcrip, isWord : true, count : 1
str : pyocmnxr, isWord : true, count : 1
str : aqsvubqrh, isWord : true, count : 1
str : fwhlgothm, isWord : true, count : 1
str : gtkunybjp, isWord : true, count : 1
str : l, isWord : false, count : 16
str : tykwoeyma, isWord : true, count : 1
str : foenehshj, isWord : true, count : 1
str : ykodlbvhk, isWord : true, count : 1
str : dpojvwruz, isWord : true, count : 1
str : pnjuamwih, isWord : true, count : 1
str : wfovkcpea, isWord : true, count : 1
str : uqbxvhcej, isWord : true, count : 1
str : h, isWord : false, count : 3
str : q, isWord : false, count : 2
str : xcmsyjw, isWord : true, count : 1
str : gtybdgz, isWord : true, count : 1
str : cwdhfljl, isWord : true, count : 1
str : asirzknwb, isWord : true, count : 1
str : j, isWord : false, count : 2
str : weavcfwf, isWord : true, count : 1
str : axobpyzy, isWord : true, count : 1
str : bssldvnod, isWord : true, count : 1
str : n, isWord : false, count : 2
str : yigypswa, isWord : true, count : 1
str : voinhset, isWord : true, count : 1
str : m, isWord : false, count : 20
str : a, isWord : false, count : 2
str : jzxvsbuq, isWord : true, count : 1
str : bnsdwxmw, isWord : true, count : 1
str : b, isWord : false, count : 2
str : evpbddpa, isWord : true, count : 1
str : ynqeqzgc, isWord : true, count : 1
str : zbdvbvcnl, isWord : true, count : 1
str : d, isWord : false, count : 2
str : ylwyxlkc, isWord : true, count : 1
str : idwxbtei, isWord : true, count : 1
str : omtbqtxei, isWord : true, count : 1
str : sdqgwgnjo, isWord : true, count : 1
str : wlmkkzwqb, isWord : true, count : 1
str : qdxpxsowd, isWord : true, count : 1
str : p, isWord : false, count : 2
str : namqmvte, isWord : true, count : 1
str : ukhcsuow, isWord : true, count : 1
str : yclsmbgvb, isWord : true, count : 1
str : u, isWord : false, count : 2
str : juovneoh, isWord : true, count : 1
str : vmttfvos, isWord : true, count : 1
str : v, isWord : false, count : 2
str : teprigjs, isWord : true, count : 1
str : qylrswml, isWord : true, count : 1
str : x, isWord : false, count : 2
str : fiuthpwm, isWord : true, count : 1
str : jjgmgxjy, isWord : true, count : 1
str : n, isWord : false, count : 18
str : wxdkvgywg, isWord : true, count : 1
str : c, isWord : false, count : 2
str : eebdkkkd, isWord : true, count : 1
str : cqdlojgh, isWord : true, count : 1
str : tudnypngd, isWord : true, count : 1
str : d, isWord : false, count : 2
str : qjvbeqoy, isWord : true, count : 1
str : gviclxjq, isWord : true, count : 1
str : vpwcaekjx, isWord : true, count : 1
str : f, isWord : false, count : 2
str : yfwyxsru, isWord : true, count : 1
str : vvtmjnlq, isWord : true, count : 1
str : olnrywqvo, isWord : true, count : 1
str : iosebaodr, isWord : true, count : 1
str : uwmoitczp, isWord : true, count : 1
str : xrsbofbtt, isWord : true, count : 1
str : ngvnhrbfs, isWord : true, count : 1
str : y, isWord : false, count : 3
str : vtqvwssx, isWord : true, count : 1
str : lplphgmh, isWord : true, count : 1
str : tcotbygo, isWord : true, count : 1
str : jdxvxxptx, isWord : true, count : 1
str : o, isWord : false, count : 14
str : kvhhlbdab, isWord : true, count : 1
str : bumffivtn, isWord : true, count : 1
str : plnebqeao, isWord : true, count : 1
str : mpwjixmmt, isWord : true, count : 1
str : tpsqklver, isWord : true, count : 1
str : u, isWord : false, count : 2
str : qpxxhiyj, isWord : true, count : 1
str : lkbfgrjq, isWord : true, count : 1
str : dkoejecvg, isWord : true, count : 1
str : nyobqxjks, isWord : true, count : 1
str : fcjhwdlcg, isWord : true, count : 1
str : rqdudbfee, isWord : true, count : 1
str : o, isWord : false, count : 3
str : rcysotjt, isWord : true, count : 1
str : sbxohfbd, isWord : true, count : 1
str : pofgixiv, isWord : true, count : 1
str : p, isWord : false, count : 27
str : nqdtikyvx, isWord : true, count : 1
str : b, isWord : false, count : 2
str : kpkqcpql, isWord : true, count : 1
str : fznlible, isWord : true, count : 1
str : c, isWord : false, count : 2
str : mhterbxy, isWord : true, count : 1
str : debpoecx, isWord : true, count : 1
str : ustwlwqjd, isWord : true, count : 1
str : jowdmdbvt, isWord : true, count : 1
str : k, isWord : false, count : 4
str : efrfnyce, isWord : true, count : 1
str : bkpoopsa, isWord : true, count : 1
str : dqyuumto, isWord : true, count : 1
str : ieubnydl, isWord : true, count : 1
str : ixrtmuhnb, isWord : true, count : 1
str : o, isWord : false, count : 2
str : ykygvgcy, isWord : true, count : 1
str : noqmgruu, isWord : true, count : 1
str : q, isWord : false, count : 2
str : xurbngrr, isWord : true, count : 1
str : zrmcwtqs, isWord : true, count : 1
str : hxlkusrvz, isWord : true, count : 1
str : mbspmgiux, isWord : true, count : 1
str : s, isWord : false, count : 2
str : cmklndaf, isWord : true, count : 1
str : tqjxoxve, isWord : true, count : 1
str : t, isWord : false, count : 2
str : zfmitvyj, isWord : true, count : 1
str : ildpdzmx, isWord : true, count : 1
str : v, isWord : false, count : 2
str : hhscedqv, isWord : true, count : 1
str : lbtgvjcs, isWord : true, count : 1
str : y, isWord : false, count : 2
str : pxtrjgqy, isWord : true, count : 1
str : jqkotwhe, isWord : true, count : 1
str : pizddnvmh, isWord : true, count : 1
str : q, isWord : false, count : 15
str : byhsnctqd, isWord : true, count : 1
str : jhnvdbkdi, isWord : true, count : 1
str : t, isWord : false, count : 2
str : zvnemtiq, isWord : true, count : 1
str : ebrcpsqe, isWord : true, count : 1
str : u, isWord : false, count : 4
str : npscqpop, isWord : true, count : 1
str : ccmypnca, isWord : true, count : 1
str : movdxpdf, isWord : true, count : 1
str : bhinjrcu, isWord : true, count : 1
str : fvmiivshy, isWord : true, count : 1
str : gyficrern, isWord : true, count : 1
str : nrnljmnsl, isWord : true, count : 1
str : pjllpuili, isWord : true, count : 1
str : wvvlevgqd, isWord : true, count : 1
str : o, isWord : false, count : 2
str : jpvlsbsu, isWord : true, count : 1
str : rudrudqj, isWord : true, count : 1
str : r, isWord : false, count : 20
str : ilubscsym, isWord : true, count : 1
str : r, isWord : false, count : 3
str : neyqpuhc, isWord : true, count : 1
str : jvlyynuu, isWord : true, count : 1
str : sxucdpiq, isWord : true, count : 1
str : s, isWord : false, count : 2
str : jmyigesh, isWord : true, count : 1
str : vcwubtml, isWord : true, count : 1
str : oxllpefko, isWord : true, count : 1
str : bcvwsogdd, isWord : true, count : 1
str : pcvotvpuq, isWord : true, count : 1
str : f, isWord : false, count : 2
str : vibimlag, isWord : true, count : 1
str : evrpfumm, isWord : true, count : 1
str : egsvvlovf, isWord : true, count : 1
str : w, isWord : false, count : 4
str : odihhdvq, isWord : true, count : 1
str : binhvwac, isWord : true, count : 1
str : dgtxcylv, isWord : true, count : 1
str : haegudbo, isWord : true, count : 1
str : xkqnixyfi, isWord : true, count : 1
str : k, isWord : false, count : 3
str : fyckhlee, isWord : true, count : 1
str : cdjtcjrq, isWord : true, count : 1
str : dhyejwsg, isWord : true, count : 1
str : s, isWord : false, count : 25
str : kcwlvxxuc, isWord : true, count : 1
str : b, isWord : false, count : 2
str : blidfzih, isWord : true, count : 1
str : vgdddnmm, isWord : true, count : 1
str : c, isWord : false, count : 4
str : cxgtfkdo, isWord : true, count : 1
str : h, isWord : false, count : 2
str : wuvcunq, isWord : true, count : 1
str : inaflrp, isWord : true, count : 1
str : tussjbav, isWord : true, count : 1
str : e, isWord : false, count : 2
str : cvvorcwz, isWord : true, count : 1
str : amlthaxk, isWord : true, count : 1
str : ldkxnmril, isWord : true, count : 1
str : gqlwnjmlf, isWord : true, count : 1
str : vqkhldfdw, isWord : true, count : 1
str : mewetpryj, isWord : true, count : 1
str : q, isWord : false, count : 4
str : oltgrppw, isWord : true, count : 1
str : c, isWord : false, count : 2
str : pkgljhj, isWord : true, count : 1
str : ctfidpz, isWord : true, count : 1
str : whxisjbg, isWord : true, count : 1
str : oduwvijdn, isWord : true, count : 1
str : xhdxhnspi, isWord : true, count : 1
str : s, isWord : false, count : 2
str : ohsvwemq, isWord : true, count : 1
str : tfitotfu, isWord : true, count : 1
str : rrdthzbqq, isWord : true, count : 1
str : y, isWord : false, count : 2
str : iubthgjs, isWord : true, count : 1
str : ejccuiwh, isWord : true, count : 1
str : jflguhwgh, isWord : true, count : 1
str : t, isWord : false, count : 14
str : dibehwpvb, isWord : true, count : 1
str : c, isWord : false, count : 2
str : hzmoycnt, isWord : true, count : 1
str : rdbppojv, isWord : true, count : 1
str : yygjpogbz, isWord : true, count : 1
str : zuusmshca, isWord : true, count : 1
str : ieuqncuud, isWord : true, count : 1
str : rwsvnhcmw, isWord : true, count : 1
str : otghtuvqo, isWord : true, count : 1
str : ugasrmtuy, isWord : true, count : 1
str : j, isWord : false, count : 2
str : nxdcehvh, isWord : true, count : 1
str : rpmyapuw, isWord : true, count : 1
str : lkoswttyr, isWord : true, count : 1
str : m, isWord : false, count : 2
str : lmdbsqml, isWord : true, count : 1
str : iqrbwxfx, isWord : true, count : 1
str : u, isWord : false, count : 20
str : xbhssncfj, isWord : true, count : 1
str : uwpofcpoc, isWord : true, count : 1
str : d, isWord : false, count : 2
str : jufrmoxn, isWord : true, count : 1
str : yxlsgsku, isWord : true, count : 1
str : qvkkobbwj, isWord : true, count : 1
str : m, isWord : false, count : 2
str : yclcwpve, isWord : true, count : 1
str : lfvbnafq, isWord : true, count : 1
str : cisxawvgp, isWord : true, count : 1
str : n, isWord : false, count : 2
str : qomvggve, isWord : true, count : 1
str : eoqcvkjc, isWord : true, count : 1
str : jlopfvfyn, isWord : true, count : 1
str : s, isWord : false, count : 3
str : iultquie, isWord : true, count : 1
str : glsdcszb, isWord : true, count : 1
str : hvtacxck, isWord : true, count : 1
str : w, isWord : false, count : 2
str : opldtdkw, isWord : true, count : 1
str : fmuoxxdy, isWord : true, count : 1
str : vpcadsief, isWord : true, count : 1
str : tsrhbsivm, isWord : true, count : 1
str : aybxoetvn, isWord : true, count : 1
str : fcvrmdfje, isWord : true, count : 1
str : v, isWord : false, count : 21
str : a, isWord : false, count : 2
str : rprkekdt, isWord : true, count : 1
str : qvcteorp, isWord : true, count : 1
str : gtqhbewsb, isWord : true, count : 1
str : b, isWord : false, count : 2
str : bbvdfabi, isWord : true, count : 1
str : wybqnobb, isWord : true, count : 1
str : lswdvufbu, isWord : true, count : 1
str : d, isWord : false, count : 2
str : cgvkugmv, isWord : true, count : 1
str : hdyvqvso, isWord : true, count : 1
str : e, isWord : false, count : 2
str : xjhewjfn, isWord : true, count : 1
str : ubusbnck, isWord : true, count : 1
str : jrkyuqfhy, isWord : true, count : 1
str : uxwlhbcdm, isWord : true, count : 1
str : v, isWord : false, count : 2
str : lwpqrkxk, isWord : true, count : 1
str : qstkbtvg, isWord : true, count : 1
str : fbkrymshl, isWord : true, count : 1
str : cuvyidufi, isWord : true, count : 1
str : z, isWord : false, count : 2
str : insawsph, isWord : true, count : 1
str : disumgpv, isWord : true, count : 1
str : oeilidftj, isWord : true, count : 1
str : pqvqhmwxk, isWord : true, count : 1
str : hbplpplns, isWord : true, count : 1
str : w, isWord : false, count : 19
str : c, isWord : false, count : 2
str : htlmjxdb, isWord : true, count : 1
str : kcytuqno, isWord : true, count : 1
str : f, isWord : false, count : 2
str : bfqitldc, isWord : true, count : 1
str : mghqdaok, isWord : true, count : 1
str : g, isWord : false, count : 2
str : phytwsfg, isWord : true, count : 1
str : gpclxbve, isWord : true, count : 1
str : h, isWord : false, count : 2
str : snichuuh, isWord : true, count : 1
str : ajqnnvnb, isWord : true, count : 1
str : bmdkoeteg, isWord : true, count : 1
str : m, isWord : false, count : 2
str : ssnhnquu, isWord : true, count : 1
str : yxuymjci, isWord : true, count : 1
str : ltwfkipuz, isWord : true, count : 1
str : q, isWord : false, count : 2
str : qmaofhux, isWord : true, count : 1
str : izjglqwe, isWord : true, count : 1
str : dkuttvjfq, isWord : true, count : 1
str : vktomypri, isWord : true, count : 1
str : rpbpttgcv, isWord : true, count : 1
str : ksrdoqsgq, isWord : true, count : 1
str : phqeihumc, isWord : true, count : 1
str : x, isWord : false, count : 23
str : rkfwgdrtg, isWord : true, count : 1
str : nbkiqhfiw, isWord : true, count : 1
str : c, isWord : false, count : 2
str : qoxcdbqn, isWord : true, count : 1
str : fknahuuc, isWord : true, count : 1
str : gbxmsbtga, isWord : true, count : 1
str : joaommefq, isWord : true, count : 1
str : yroekddqh, isWord : true, count : 1
str : uihdqbzxy, isWord : true, count : 1
str : o, isWord : false, count : 2
str : uremdykm, isWord : true, count : 1
str : hnbikpte, isWord : true, count : 1
str : q, isWord : false, count : 2
str : emgreolm, isWord : true, count : 1
str : ssxplvcl, isWord : true, count : 1
str : s, isWord : false, count : 2
str : ffnphust, isWord : true, count : 1
str : aiijhflt, isWord : true, count : 1
str : hwfhcwjzy, isWord : true, count : 1
str : t, isWord : false, count : 2
str : fpeymosg, isWord : true, count : 1
st
主要应用场景:
搜索提示框,不过这些功能现在其实大部分被搜索引擎(如elasticsearch等)用的已经很成熟了,这篇文章也算是一个对树使用的非常好的例子.