Java Trie实现
我正在尝试用Java实现一个非常简单的Trie,它支持3个操作。我希望它有一个insert方法、一个has方法(即trie中的某个单词)和一个toString方法以字符串形式返回trie。我相信我的插入工作正常,但has和toString被证明是困难的。这是我到目前为止所拥有的 trie类Java Trie实现,java,trie,abstract-data-type,radix,radix-tree,Java,Trie,Abstract Data Type,Radix,Radix Tree,我正在尝试用Java实现一个非常简单的Trie,它支持3个操作。我希望它有一个insert方法、一个has方法(即trie中的某个单词)和一个toString方法以字符串形式返回trie。我相信我的插入工作正常,但has和toString被证明是困难的。这是我到目前为止所拥有的 trie类 public class CaseInsensitiveTrie implements SimpleTrie { //root node private TrieNode r;
public class CaseInsensitiveTrie implements SimpleTrie {
//root node
private TrieNode r;
public CaseInsensitiveTrie() {
r = new TrieNode();
}
public boolean has(String word) throws InvalidArgumentUosException {
return r.has(word);
}
public void insert(String word) throws InvalidArgumentUosException {
r.insert(word);
}
public String toString() {
return r.toString();
}
public static void main(String[] args) {
CaseInsensitiveTrie t = new CaseInsensitiveTrie();
System.out.println("Testing some strings");
t.insert("TEST");
t.insert("TATTER");
System.out.println(t.has("TEST"));
}
}
和节点类
public class TrieNode {
//make child nodes
private TrieNode[] c;
//flag for end of word
private boolean flag = false;
public TrieNode() {
c = new TrieNode[26]; //1 for each letter in alphabet
}
protected void insert(String word) {
int val = word.charAt(0) - 64;
//if the value of the child node at val is null, make a new node
//there to represent the letter
if (c[val] == null) {
c[val] = new TrieNode();
}
//if word length > 1, then word is not finished being added.
//otherwise, set the flag to true so we know a word ends there.
if (word.length() > 1) {
c[val].insert(word.substring(1));
} else {
c[val].flag = true;
}
}
public boolean has(String word) {
int val = word.charAt(0) - 64;
if (c[val]!=null && word.length()>1) {
c[val].has(word.substring(1));
} else if (c[val].flag==true && word.length()==1) {
return true;
}
return false;
}
public String toString() {
return "";
}
}
因此,基本上,当创建一个Trie时,一个三元组被创建为具有26个子级的根。当尝试插入时,将在该根节点上调用insert,从而在正确的位置递归创建一个新节点,并继续执行,直到单词完成。我相信这个方法是有效的
我的has函数非常糟糕,因为出于某种原因,我不得不将返回语句放在括号之外。我不能将它包含在else子句中,否则编译器会抱怨。除此之外,我认为该方法应该进行一些调整,但我无法为自己的生活找到答案
toString是我试图对付的野兽,但我扔给它的东西都不管用,所以在我解决问题之前,我会一直保持这种状态。如果我开始工作,我可能会想出一种方法,将其重新格式化为toString函数
int val=word.charAt(0)-64的用途;这是因为输入的每个字符串都必须是大写的(我将创建一个字符串格式化函数,以确保以后可以这样做),所以第一个字母的int值-64将是它在数组中的位置。ie数组索引0是A,所以A=64,A-64=0。B=65,B-64=1,依此类推。您的
具有
函数可能如下所示:
if (c[val]!=null && word.length()>1) {
return c[val].has(word.substring(1)); //<-- Change is on this line
} else if (c[val].flag==true && word.length()==1) {
...etc
if(c[val]!=null&&word.length()>1){
返回c[val].has(word.substring(1));//也许您可以使用“Map c”而不是“triode[]c”,这将允许您对所有类型的字符大小写甚至特殊字符使用它,甚至可以节省空间(在每个字符级别分配26个字符数组)实现和以下是我的实现:-
public class Tries {
class Node {
HashMap<Character, Node> children;
boolean end;
public Node(boolean b){
children = new HashMap<Character, Tries.Node>();
end = false;
}
}
private Node root;
public Tries(){
root = new Node(false);
}
public static void main(String args[]){
Tries tr = new Tries();
tr.add("dog");
tr.add("doggy");
System.out.println(tr.search("dogg"));
System.out.println(tr.search("doggy"));
}
private boolean search(String word) {
Node crawl = root;
int n = word.length();
for(int i=0;i<n;i++){
char ch = word.charAt(i);
if(crawl.children.get(ch) == null){
return false;
}
else {
crawl = crawl.children.get(ch);
if(i==n-1 && crawl.end == true){
return true;
}
}
}
return false;
}
private void add(String word) {
Node crawl = root;
int n = word.length();
for(int i=0;i<n;i++){
char ch = word.charAt(i);
if(crawl.children.containsKey(ch)){
crawl = crawl.children.get(ch);
}
else {
crawl.children.put(ch, new Node(false));
Node temp = crawl.children.get(ch);
if(i == n-1){
temp.end = true;
}
crawl = temp;
System.out.println(ch + " " + crawl.end);
}
}
}
}
公共类尝试{
类节点{
HashMap儿童;
布尔端;
公共节点(布尔b){
children=newhashmap();
结束=假;
}
}
私有节点根;
公开审判{
root=新节点(false);
}
公共静态void main(字符串参数[]){
trys tr=新尝试();
tr.add(“dog”);
tr.add(“doggy”);
System.out.println(tr.search(“dogg”);
System.out.println(tr.search(“doggy”);
}
专用布尔搜索(字符串字){
节点爬网=根;
int n=word.length();
对于(inti=0;i,这里是一个简单的java实现,不使用任何其他数据结构
import java.util.ArrayList;
import java.util.List;
class Trie {
private static Node root = new Node(' ', false);
static int getIndex(char x) {
return ((int) x) - ((int) 'a');
}
static class Node {
char data;
boolean isLeaf;
Node[] children;
Node(char data, boolean leaf) {
this.data = data;
this.isLeaf = leaf;
this.children = new Node[26];
}
}
static void insert(String data, Node root) {
if (data == null || data.length() == 0) {
return;
}
Node child = root.children[getIndex(data.charAt(0))];
if (child == null) {
Node node = new Node(data.charAt(0), data.length() == 1);
root.children[getIndex(data.charAt(0))] = node;
if (data.length() > 1) {
insert(data.substring(1, data.length()), node);
}
} else {
if (data.length() == 1) {
child.isLeaf = true;
} else {
insert(data.substring(1, data.length()), child);
}
}
}
static boolean find(String data, Node root) {
if (data == null || data.length() == 0) {
return true;
}
char x = data.charAt(0);
//note that first node ie root is just dummy, it just holds important
Node node = root.children[getIndex(x)];
if (node == null) {
return false;
} else {
if (data.length() == 1) {
return node.isLeaf;
} else {
return find(data.substring(1, data.length()), node);
}
}
}
static boolean delete(String data, Node root) {
if (data == null || data.length() == 0) {
return false;
}
char x = data.charAt(0);
//note that first node ie root is just dummy, it just holds important
Node node = root.children[getIndex(x)];
if (node == null) {
return false;
} else {
if (data.length() == 1) {
node.isLeaf = false;
boolean allNull = true;
for (Node node1 : node.children) {
allNull = allNull && node1 == null;
}
return allNull;
} else {
boolean delete = delete(data.substring(1, data.length()), node);
if (delete) {
node.children[getIndex(x)] = null;
if(node.isLeaf){
return false;
}
boolean allNull = true;
for (Node node1 : node.children) {
allNull = allNull && node1 == null;
}
return allNull; }
}
}
return false;
}
private static List<String> strings = new ArrayList<>();
private static List<String> getAll() {
strings = new ArrayList<String>();
findAllDFS(root, "");
return strings;
}
private static void findAllDFS(Node node, String old) {
if (node != null) {
if (node.data != ' ') {
old = old + node.data;
}
if (node.isLeaf) {
strings.add(old);
}
for (Node node1 : node.children) {
findAllDFS(node1, old);
}
}
}
public static void main(String[] args) {
insert("abc", root);
insert("xyz", root);
insert("abcd", root);
insert("abcde", root);
delete("abcd", root);
/* System.out.println(find("abc", root));
System.out.println(find("abcd", root));
System.out.println(find("ab", root));
System.out.println(find("xyz", root));*/
System.out.println(getAll());
}
}
import java.util.ArrayList;
导入java.util.List;
三类{
私有静态节点根=新节点(“”,false);
静态int getIndex(char x){
返回((int)x)-(int)“a”);
}
静态类节点{
字符数据;
布尔孤岛;
节点[]子节点;
节点(字符数据,布尔叶){
这个数据=数据;
this.isLeaf=leaf;
this.children=新节点[26];
}
}
静态void插入(字符串数据、节点根){
if(data==null | | data.length()==0){
返回;
}
Node child=root.children[getIndex(data.charAt(0));
if(child==null){
Node Node=新节点(data.charAt(0),data.length()=1);
root.children[getIndex(data.charAt(0))]=node;
if(data.length()>1){
插入(data.substring(1,data.length()),节点);
}
}否则{
if(data.length()==1){
child.isLeaf=true;
}否则{
插入(data.substring(1,data.length()),子字符串);
}
}
}
静态布尔查找(字符串数据,节点根){
if(data==null | | data.length()==0){
返回true;
}
char x=data.charAt(0);
//请注意,第一个节点ie根只是一个伪节点,它只包含重要节点
Node=root.children[getIndex(x)];
if(node==null){
返回false;
}否则{
if(data.length()==1){
返回node.isLeaf;
}否则{
返回find(data.substring(1,data.length()),node);
}
}
}
静态布尔删除(字符串数据,节点根){
if(data==null | | data.length()==0){
返回false;
}
char x=data.charAt(0);
//请注意,第一个节点ie根只是一个伪节点,它只包含重要节点
Node=root.children[getIndex(x)];
if(node==null){
返回false;
}否则{
if(data.length()==1){
node.isLeaf=false;
布尔值allNull=true;
for(节点1:Node.children){
allNull=allNull&&node1==null;
}
返回allNull;
}否则{
布尔delete=delete(data.substring(1,data.length()),节点);
如果(删除){
node.children[getIndex(x)]=null;
if(node.isLeaf){
返回false;
}
布尔值allNull=true;
for(节点1:Node.children){
allNull=allNull&&node1==null;
}
返回allNull;}
}
}
返回false;
}
私有静态列表字符串=新的ArrayList();
私有静态列表getAll(){
strings=newarraylist();
findAllDFS(根“”);
返回字符串;
}
私有静态void findAllDFS(节点节点,字符串旧){
如果(节点!=null){
如果(node.data!=''){
old=old+node.data;
}
if(node.isLeaf){
public class Tries {
private static class Leaf {
private Leaf(char c) {
this.c=c;
}
char c;
int counter = 1;
List<Leaf> leaves = new ArrayList<>(10);
}
private Leaf root = new Leaf('0');
public void add(String word) {
Leaf current = root;
Leaf newLeaf = null;
for (char c : word.toCharArray()) {
boolean found = false;
for (Leaf leaf : current.leaves) {
if (leaf.c == c) {
current = leaf;
current.counter++;
found=true;
break;
}
}
if (!found) {
newLeaf = new Leaf(c);
current.leaves.add(newLeaf);
current = newLeaf;
}
}
}
public int find(String partial) {
Leaf current = root;
for (char c : partial.toCharArray()) {
boolean found = false;
for (Leaf leaf : current.leaves) {
if (leaf.c == c) {
current=leaf;
found=true;
break;
}
}
if(!found) return 0;
}
return current.counter;
}
public boolean hasWord(String partial) {
return find(partial)>0;
}
}