首页 文章

在Java中实现Trie

提问于
浏览
0

我用Java实现了Trie数据结构,但是在运行代码时没有得到正确的答案 . 我用一些简单的字符串构建了trie . 我正在搜索单词和前缀,但结果不合适 . 我已经尝试了很多调试但仍然找不到它可能出错的地方 .

Trie.java:

public class Trie {

    public class Vertex {
        public int words;
        public int prefixes;
        public Vertex edges[] = new Vertex[26];

        public Vertex() {
            this.words = 0;
            this.prefixes = 0;
        }
    }

    private Vertex root;

    Trie() {
        this.root = new Vertex();
    }

    private void addWord(Vertex vertex, String word) {
        if (word.isEmpty()) {
            vertex.words++;
        } else {
            vertex.prefixes++;
            int indexOfNextChar = (int) word.charAt(0) - 97;
            vertex.edges[indexOfNextChar] = new Vertex();
            this.addWord(vertex.edges[indexOfNextChar], word.substring(1));
        }
    }

    private int countWords(Vertex vertex, String word) {
        if (!word.isEmpty()) {
            int indexOfNextChar = (int) word.charAt(0) - 97;
            if (vertex.edges[indexOfNextChar] == null) {
                return 0;
            } else {
                return this.countWords(vertex.edges[indexOfNextChar], word.substring(1));
            }
        } else {
            return vertex.words;
        }
    }

    private int countPrefixes(Vertex vertex, String word) {
        if (!word.isEmpty()) {
            int indexOfNextChar = (int) word.charAt(0) - 97;
            if (vertex.edges[indexOfNextChar] == null) {
                return 0;
            } else {
                return this.countPrefixes(vertex.edges[indexOfNextChar], word.substring(1));
            }
        } else {
            return vertex.prefixes;
        }
    }

    public void addWord(String word) {
        this.addWord(this.root, word.toLowerCase());
    }

    public int countPrefixes(String word) {
        if (word.length() != 0) {
            return this.countPrefixes(this.root, word.toLowerCase());
        }
        return -1;
    }

    public int countWords(String word) {
        if (word.length() != 0) {
            return this.countWords(this.root, word.toLowerCase());
        }
        return -1;
    }
}

TrieTester.java

public class TrieTester {
    public static void main(String[] args) {
        Trie trie = new Trie();
        trie.addWord("Ayush");
        trie.addWord("Ayur");
        trie.addWord("Ayub");
        trie.addWord("Ayan");
        trie.addWord("Bhushan");

        // Should output 0, outputs 0
        System.out.println("Count of word Ayus: " + trie.countWords("Ayus"));

        // Should output 1, outputs 0
        System.out.println("Count of word Ayush: " + trie.countWords("Ayush"));

        // Should output 4, outputs 1
        System.err.println("Count of prefix Ay: " + trie.countPrefixes("Ay"));
    }
}

我提到Topcoder Trie tutorial来实现这一点 .

1 回答

  • 1

    addWord 方法中的 else 子句肯定是不正确的(可能还有其他错误):

    vertex.prefixes++;
    int indexOfNextChar = (int) word.charAt(0) - 97;
    vertex.edges[indexOfNextChar] = new Vertex();
    this.addWord(vertex.edges[indexOfNextChar], word.substring(1));
    

    您的代码始终会创建一个新顶点 . 那是错的 . 当且仅当给定角色没有边缘时,你应该这样做 . 也就是说,应该是这样的:

    if (vertex.edges[indexOfNextChar] == null) {
        vertex.edges[indexOfNextChar] = new Vertex();
    }
    

    您的实施还有一些其他问题 . 例如, String.substring 方法在线性时间内工作,因此向trie添加字符串需要二次时间 . 您可以通过迭代单词的所有字符而不是对其子字符串进行递归来解决此问题 . 消除递归也是一个好主意,因为你可以在更长的字符串中遇到堆栈溢出错误 .

相关问题