【问题标题】:Array Index out of range while retrieving string from TRIE data structure?从 TRIE 数据结构中检索字符串时数组索引超出范围?
【发布时间】:2014-04-16 18:18:04
【问题描述】:

我将字符串及其频率存储在 TRIE 数据结构中

hello 100
world 5000
good 2000
bad 9000

下面是我的TrieImpl

public class TrieImpl {

    //root node
    private TrieNode r;

    public TrieImpl() {
        r = new TrieNode();
    }

    public int find(String word) {
        return r.getFreq(word);
    }

    public void insert(String word, int freq) {
        r.insert(word, freq);
    }

    public String toString() {
        return r.toString();
    }

    public static void main(String[] args) {

        TrieImpl t = new TrieImpl();

        System.out.println("Testing some strings");
        // storing strings and its frequencies
        t.insert("HELLO", 10);
        t.insert("WORLD", 20);

        System.out.println(t.find("HELLO"));
        System.out.println(t.find("HELLO1")); // this line throws Array Index Out of Range
    }
}

下面是我的TrieNode class -

public class TrieNode {

    // make child nodes
    private TrieNode[] c;
    // flag for end of word
    private boolean flag = false;
    // stores frequency if flag is set
    private int frequency;

    public TrieNode() {
        c = new TrieNode[26];
    }

    protected void insert(String word, int frequency) {
        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 the value of the child node at val is null, make a new nod
        if (word.length() > 1) {
            c[val].insert(word.substring(1), frequency);
        } else {
            c[val].flag = true;
            c[val].frequency = frequency;
        }
    }


    public int getFreq(String word) {
        int val = word.charAt(0) - 64;
        if (word.length() > 1) {
            return c[val].getFreq(word.substring(1));
        } else if (c[val].flag == true && word.length() == 1) {
            return c[val].frequency;
        } else
            return -1;
    }


    public String toString() {
    return c.toString();
    }
}

我能够在 TRIE 中插入字符串及其频率,还能够查找已经存在的给定字符串的频率。现在我面临的问题是 - 如果我正在查找 TRIE 中不存在的字符串,它会抛出 Arrays Index Out of Range 错误。

如果您看到我上面的 TrieImpl 类,我正在搜索 TRIE 中不存在的字符串 HELLO1,因此对于这种情况,它会抛出 ArrayIndex 超出范围。

有什么办法解决这个问题吗?

【问题讨论】:

    标签: java data-structures trie


    【解决方案1】:

    您应该简单地检查val 是否会超出您的getFreq 函数的范围。

    您可能还需要检查目标索引处是否确实有一个元素(即它不是null)。

    另外,正如另一个答案中所指出的那样,您正在将“无效”字符串传递给您的函数,因为 1 导致负的 val 值/索引 - 您应该避免这样做,或者您也可以将该检查添加到您的函数中。

    public int getFreq(String word) {
      int val = word.charAt(0) - 64;
      if (val < 0 || val >= c.length || c[val] == null)
        return -1;
      ...
    }
    

    【讨论】:

    • 谢谢,那么我的全部功能会是什么样子?如果在我的方法顶部检查,我只需要添加它?
    • 是的,您只需要将检查添加到方法的顶部。
    • 谢谢。那个问题得到了解决。另一个快速的问题,它与此无关,但它是相同的数组索引超出范围异常。每当我插入下大写 hello 时,它会在 if (c[val] == null) { 处抛出 java.lang.ArrayIndexOutOfBoundsException 但如果我插入所有上大写 HELLO 它工作正常。有什么想法可能是什么原因?
    • 你的数组只有 26 长。查看a Unicode table,您会看到小写字母出现在大写字母之后,中间还有一些其他字符。因此,如果您想同时满足两者,则需要增加大小(或者如果您希望它不区分大小写,则单独处理它们)。另外,你应该-65,而不是-64(或者,更好的是-'A'),让A成为0,而不是1
    • 谢谢杜克。我需要处理这两种情况,所以我应该在这里使用什么尺寸才能使一切顺利进行?而且我也改成 -65 而不是 -64。
    【解决方案2】:

    您正在使用:t.find("HELLO1"),它将被传递给您的 getFreq() 函数。

    它将继续使用ELLO1LLO1LO1O1调用getFreq()

    此时,由于您的递归方法,当实现仅使用单词 1 重试它时,它将导致 int val = word.charAt(0) - 64; // 49-64 并且这是 val = -15 的值 - 这不是有效的数组索引。

    【讨论】:

    • 啊啊..感谢您的帮助。那么我的方法一般应该是什么样子呢?
    • @dognose word.charAt(0) for '1' 将是 49 对吗? ASCII 值?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 2016-02-19
    相关资源
    最近更新 更多