package class05; import java.util.HashMap; // 该程序完全正确 public class Code02_TrieTree { public static class Node1 { public int pass; public int end; public Node1[] nexts; public Node1() { pass = 0; end = 0; // 0 a // 1 b // 2 c // .. .. // 25 z // nexts[i] == null i方向的路不存在 // nexts[i] != null i方向的路存在 nexts = new Node1[26]; } } public static class Trie1 { private Node1 root; public Trie1() { root = new Node1(); } public void insert(String word) { if (word == null) { return; } char[] str = word.toCharArray(); Node1 node = root; node.pass++; int path = 0; for (int i = 0; i < str.length; i++) { // 从左往右遍历字符 path = str[i] - 'a'; // 由字符,对应成走向哪条路 if (node.nexts[path] == null) { node.nexts[path] = new Node1(); } node = node.nexts[path]; node.pass++; } node.end++; } public void delete(String word) { if (search(word) != 0) { char[] chs = word.toCharArray(); Node1 node = root; node.pass--; int path = 0; for (int i = 0; i < chs.length; i++) { path = chs[i] - 'a'; if (--node.nexts[path].pass == 0) { node.nexts[path] = null; return; } node = node.nexts[path]; } node.end--; } } // word这个单词之前加入过几次 public int search(String word) { if (word == null) { return 0; } char[] chs = word.toCharArray(); Node1 node = root; int index = 0; for (int i = 0; i < chs.length; i++) { index = chs[i] - 'a'; if (node.nexts[index] == null) { return 0; } node = node.nexts[index]; } return node.end; } // 所有加入的字符串中,有几个是以pre这个字符串作为前缀的 public int prefixNumber(String pre) { if (pre == null) { return 0; } char[] chs = pre.toCharArray(); Node1 node = root; int index = 0; for (int i = 0; i < chs.length; i++) { index = chs[i] - 'a'; if (node.nexts[index] == null) { return 0; } node = node.nexts[index]; } return node.pass; } } public static class Node2 { public int pass; public int end; public HashMap<Integer, Node2> nexts; public Node2() { pass = 0; end = 0; nexts = new HashMap<>(); } } public static class Trie2 { private Node2 root; public Trie2() { root = new Node2(); } public void insert(String word) { if (word == null) { return; } char[] chs = word.toCharArray(); Node2 node = root; node.pass++; int index = 0; for (int i = 0; i < chs.length; i++) { index = (int) chs[i]; if (!node.nexts.containsKey(index)) { node.nexts.put(index, new Node2()); } node = node.nexts.get(index); node.pass++; } node.end++; } public void delete(String word) { if (search(word) != 0) { char[] chs = word.toCharArray(); Node2 node = root; node.pass--; int index = 0; for (int i = 0; i < chs.length; i++) { index = (int) chs[i]; if (--node.nexts.get(index).pass == 0) { node.nexts.remove(index); return; } node = node.nexts.get(index); } node.end--; } } // word这个单词之前加入过几次 public int search(String word) { if (word == null) { return 0; } char[] chs = word.toCharArray(); Node2 node = root; int index = 0; for (int i = 0; i < chs.length; i++) { index = (int) chs[i]; if (!node.nexts.containsKey(index)) { return 0; } node = node.nexts.get(index); } return node.end; } // 所有加入的字符串中,有几个是以pre这个字符串作为前缀的 public int prefixNumber(String pre) { if (pre == null) { return 0; } char[] chs = pre.toCharArray(); Node2 node = root; int index = 0; for (int i = 0; i < chs.length; i++) { index = (int) chs[i]; if (!node.nexts.containsKey(index)) { return 0; } node = node.nexts.get(index); } return node.pass; } } public static class Right { private HashMap<String, Integer> box; public Right() { box = new HashMap<>(); } public void insert(String word) { if (!box.containsKey(word)) { box.put(word, 1); } else { box.put(word, box.get(word) + 1); } } public void delete(String word) { if (box.containsKey(word)) { if (box.get(word) == 1) { box.remove(word); } else { box.put(word, box.get(word) - 1); } } } public int search(String word) { if (!box.containsKey(word)) { return 0; } else { return box.get(word); } } public int prefixNumber(String pre) { int count = 0; for (String cur : box.keySet()) { if (cur.startsWith(pre)) { count += box.get(cur); } } return count; } } // for test public static String generateRandomString(int strLen) { char[] ans = new char[(int) (Math.random() * strLen) + 1]; for (int i = 0; i < ans.length; i++) { int value = (int) (Math.random() * 6); ans[i] = (char) (97 + value); } return String.valueOf(ans); } // for test public static String[] generateRandomStringArray(int arrLen, int strLen) { String[] ans = new String[(int) (Math.random() * arrLen) + 1]; for (int i = 0; i < ans.length; i++) { ans[i] = generateRandomString(strLen); } return ans; } public static void main(String[] args) { int arrLen = 100; int strLen = 20; int testTimes = 100000; for (int i = 0; i < testTimes; i++) { String[] arr = generateRandomStringArray(arrLen, strLen); Trie1 trie1 = new Trie1(); Trie2 trie2 = new Trie2(); Right right = new Right(); for (int j = 0; j < arr.length; j++) { double decide = Math.random(); if (decide < 0.25) { trie1.insert(arr[j]); trie2.insert(arr[j]); right.insert(arr[j]); } else if (decide < 0.5) { trie1.delete(arr[j]); trie2.delete(arr[j]); right.delete(arr[j]); } else if (decide < 0.75) { int ans1 = trie1.search(arr[j]); int ans2 = trie2.search(arr[j]); int ans3 = right.search(arr[j]); if (ans1 != ans2 || ans2 != ans3) { System.out.println("Oops!"); } } else { int ans1 = trie1.prefixNumber(arr[j]); int ans2 = trie2.prefixNumber(arr[j]); int ans3 = right.prefixNumber(arr[j]); if (ans1 != ans2 || ans2 != ans3) { System.out.println("Oops!"); } } } } System.out.println("finish!"); } }
01-21
478
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
01-08
254
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
10-03
404
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
09-05
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交