将字典实现为通用树

时间:2016-03-07 12:55:49

标签: java tree

我有一个enlish词典,这是一个包含enlish词汇列表的文件(一行代表)。 我必须在像通用树这样的数据结构中出现这个字典。 所以我想要这样的东西:

Dictionary = [
    TA: Tree that rapresent words that starts with 'a':
                .a
           / | \  ... \
          .a .b   ... .z
          /|\         /|\
                ...   

    TB: Tree that rapresent words that starts with 'b':
                .b
           / | \  ... \
          .a .b   ... .z
          /|\         /|\ 
                ... 

                ...

    TZ: Tree that rapresent words that starts with 'bz':
                .z
           / | \  ... \
          .a .b   ... .z            
          /|\         /|\ 
                ... 
]

根和节点之间的路径是一个单词(或一个单词)。

这样做的最佳方式是什么?

现在我已经创建了一个类Node:

public class Node {
    private static char ch;   
    private static int count;

    Node(char ch, int count) {
        this.ch = ch;
        this.count = count;
    }

    Node(char ch) {
        this.ch = ch;
    }

    Node(int count) {
        this.count = count;
    }

    public static char getChar() {
        return ch;
    } 

    public static int getCount() {
        return count;
    } 

    public static int incrementCounter() {
        return count++;
    }

    public String toString() {
        String s = "";
        s += "'" + ch + "' (" + count + ") ";
        return s;
    }
}

然后我想做类似的事情:

public class GenericTreeNode<Node> {

    public Node data;
    public List<GenericTreeNode<Node>> children;

    ...
}

但是这样做,我将生成像TA,TB,...,TZ这样的通用树,而不是整个词典。 或者不是?

有人可以帮助我吗?

由于

2 个答案:

答案 0 :(得分:0)

我认为你不需要GenericTreeNode课程来达到这个目的。您可以扩展您的Node课程以包括以下儿童。

public class Node {

    private char mChar;
    private Set<Node> mChildren;
    //declare other variables you need here

    public Node(char c) {
        mChar = c;
        mChildren = new HashSet<Node>();
    }

    public Node addChild(Node node) {
        mChildren.add(node);
        return node;
    }

    public char getChar() {
        return mChar;
    }
}

创建这样的Node类后,您可以按如下方式生成树结构。

public void buildTree() {
    //use any non alphabet character for root node.
    //used '*' here. 
    Node root = new Node('*');
    //add child 'a'
    Node a = new Node('a');
    root.addChild(a);

    //add child 'ab'
    a.addChild(new Node('b'));

    //add child 'efg'
    root.addChild(new Node('e')).addChild(new Node('f')).addChild(new Node('g'));
}

我希望你能得到主要的想法。它是创建一个具有值的Node类,并且还包含一组Node相同类型的子项。实现此功能后,您可以生成任意深度的树结构。

注意:您已在private static char ch;课程中声明Node。您不应将其声明为静态。如果是这样,您将无法为不同节点中的变量ch分配不同的值

答案 1 :(得分:0)

您可以懒惰地实例化节点并存储在地图中。因此,您遍历字符串字符并创建子节点。

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class DictionaryTree {

    private final Map<Character, Node> rootNodes;

    public DictionaryTree() {
        rootNodes = new HashMap<>();
    }

    private Node getRootOrCreate(char ch) {
        Node root = rootNodes.get(ch);

        if (root == null) {
            root = new Node(ch);
            rootNodes.put(ch, root);
        }

        return root;
    }

    public void addWord(String word) {
        Node current = getRootOrCreate(word.charAt(0));

        for (int i = 1; i < word.length(); i++) {
            current = current.addChild(word.charAt(i));
        }
    }

    public static class Node {

        private char ch;
        private Map<Character, Node> children;

        public Node(char ch) {
            this.ch = ch;
            this.children = new LinkedHashMap<>();
        }

        public char getChar() {
            return ch;
        }

        public Node addChild(char ch) {
            Node node = children.get(ch);
            if (node == null) {
                node = new Node(ch);
                children.put(ch, node);
            }
            return node;
        }

        public String toString() {
            StringBuilder stringBuilder = new StringBuilder(ch);
            stringBuilder.append(", children: ");

            stringBuilder.append(children.values()
                                    .stream()
                                    .map(n -> String.valueOf(n.getChar()))
                                    .collect(Collectors.joining(", ")));

            return stringBuilder.toString();
        }
    }

    public static void main(String[] args) {
        String[] words = new String[] { "foo", "bar", "baz" };

        DictionaryTree tree = new DictionaryTree();

        for (String word : words) {
            tree.addWord(word);
        }
    }

}