【问题标题】:Java Suffix Trie exceeding heap spaceJava Suffix Trie 超出堆空间
【发布时间】:2011-11-09 23:40:20
【问题描述】:

我正在实现一个后缀树(这与后缀树不同),它将字符串的字符后缀存储为树结构中的节点,其中通过遍历树直到您点击“$”或您已经完成了搜索。

问题在于,在使用大型文本文件时,构造这个 trie 会比 Java 消耗更多的内存。就数据结构而言,有没有可以减少内存使用的地方?这是家庭作业,不需要将其制成压缩后缀树(基本上是后缀树)。

这是我目前拥有的基本结构(如果你真的想要,我可以提供实现细节):

// SuffixTrie.java

public class SuffixTrie {
    private SuffixTrieNode root = new SuffixTrieNode();

    // implementation of insertions into tree etc..


    public static void main(String[] args) throws FileNotFoundException {   
        String fileName = "Frankenstein.txt";
        SuffixTrie st = readInFromFile(fileName);
        String[] ss = {"without","hideous", "the only", "onster", ", the", "ngeuhhh"};
        for (String s: ss) {
            SuffixTrieNode sn = st.get(s);
            System.out.println("[" + s + "]: " + sn);
        }
    }
}

每个节点是:

// SuffixTrieNode.java
public class SuffixTrieNode {
    private char label; // Indicates the letter for this node
    private boolean isTerminal = false;
    private SuffixTrieData data;
    private HashSet<SuffixTrieNode> children; 
 // Inserting adds more SuffixTrieNodes to the children of the node

每个节点保存的数据是:

public class SuffixTrieData {
    private ArrayList<Pair> startIndexes = new ArrayList<Pair>();

    public SuffixTrieData(int sentence, int index){
        addStartIndex(sentence, index);
    }   
    public class Pair{
        public int sentence;
        public int index;
        public Pair(int sentence, int index){
            this.sentence = sentence;
            this.index = index;
        }
    }
}

我得到的错误是:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.ArrayList.<init>(Unknown Source)
    at java.util.ArrayList.<init>(Unknown Source)
    at SuffixTrieData.<init>(SuffixTrieData.java:7)
    at SuffixTrie.insert(SuffixTrie.java:20)
    at SuffixTrie.insert(SuffixTrie.java:11)
    at SuffixTrie.readInFromFile(SuffixTrie.java:77)
    at SuffixTrie.main(SuffixTrie.java:89)

虽然它适用于较小的文本文件,但这是他们第一次给学生这个作业,所以教师不知道这是否可以通过后缀 trie 实现..

【问题讨论】:

  • 如果你有足够的内存,我相信这是可行的。如果文件对于您拥有的内存量来说太多数据,则需要使用内存效率更高的数据结构。
  • @Peter 我们必须使用后缀树,这是作业的一部分
  • 减少内存的最简单方法是使用private List&lt;Pair&gt; startIndexes = new ArrayList&lt;Pair&gt;(1);,同样可以减少Set的初始容量。
  • 尝试压缩后缀树。请参阅我在stackoverflow.com/questions/8300364/…的回复

标签: java data-structures suffix-tree


【解决方案1】:

后缀特里将仅用于单词(字母)的大量空间。此外,您似乎正在存储带有索引的单词出现的每个句子的数组(您发布的代码不完整,如果我错了,请纠正我)。如果文件相当大……那会占用一些空间。

您可以做的一件事是在存储时压缩句子,并在使用 deflate/inflate 检索它们时解压缩。

除此之外,您可能希望在运行进程时增加 JVM 的堆大小,使用 -Xmx 选项(例如 java -Xmx 2GB -jar myJarFile.jar)。

【讨论】:

  • 取每个句子的后缀。将每个单词存储在节点中会简单得多,但是规范要求我们需要能够搜索部分单词,例如。 'onster'。
  • 不太清楚你的意思。一个普通的后缀 trie 不会有这样的东西。你确定你在做你应该做的事吗?
【解决方案2】:

两种解决方案:要么构建一个更轻的结构(每个模式一个数组列表和一个哈希集很多),或者,如果这是你的最佳解决方案,你可以使用 -mx-ms 命令行选项来阻塞你的程序跑进去。

【讨论】:

    猜你喜欢
    • 2015-02-22
    • 2019-03-14
    • 2021-09-09
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    相关资源
    最近更新 更多