Java Suffix Trie превышает объем кучи

Я реализую дерево суффиксов (это отличается от дерева суффиксов), которое хранит суффиксы символов строк в виде узлов в древовидной структуре, где строка составляется путем обхода дерева до тех пор, пока вы не нажмете «$» или не нажмете конец вашего поиска.

Проблема в том, что при построении этого дерева потребляется больше памяти, чем в Java при использовании большого текстового файла. Есть ли место, где я мог бы сократить использование памяти с точки зрения структур данных? Это домашнее задание, и нет необходимости делать его сжатым деревом суффиксов (которое в основном представляет собой дерево суффиксов).

Это базовая структура, которая у меня есть в настоящее время (я могу предоставить детали реализации, если вы действительно хотите):

// СуффиксTrie.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)

Однако он отлично работает для небольших текстовых файлов, и они впервые дали студентам это задание, поэтому преподаватели в любом случае не знают, выполнимо ли это с помощью суффикса.


person Jonno_FTW    schedule 04.09.2011    source источник
comment
Я уверен, что это выполнимо, если у вас достаточно памяти. Если в файле слишком много данных для имеющегося у вас объема памяти, вам необходимо использовать более эффективную структуру данных.   -  person Peter Lawrey    schedule 04.09.2011
comment
@Peter, мы должны использовать суффикс, это часть задания.   -  person Jonno_FTW    schedule 04.09.2011
comment
Самое простое, что вы можете сделать, чтобы уменьшить объем памяти, это использовать private List<Pair> startIndexes = new ArrayList<Pair>(1); аналогично тому, как вы можете уменьшить начальную емкость набора.   -  person Peter Lawrey    schedule 04.09.2011
comment
Попробуйте сжатое дерево суффиксов. См. мой ответ на stackoverflow.com/questions /8300364/   -  person Adrian    schedule 16.12.2011


Ответы (2)


Суффиксная попытка будет использовать много места только для слов (букв). Кроме того, кажется, что вы храните массив каждого предложения, в котором встречается слово, с индексом (код, который вы публикуете, неполный, поправьте меня, если я ошибаюсь). Если файл довольно большой... он займет некоторое место.

Одна вещь, которую вы можете сделать, это сжимать предложения при сохранении и распаковывать их при их извлечении с помощью deflate/inflate.

Кроме того, вы, вероятно, захотите увеличить размер кучи для JVM при запуске процесса, используя параметр -Xmx (например, java -Xmx 2GB -jar myJarFile.jar).

person Brian Roach    schedule 04.09.2011
comment
Он принимает суффиксы каждого предложения. Было бы намного проще хранить каждое слово в узле, но спецификация требует, чтобы мы могли искать частичные слова, например. 'онстер'. - person Jonno_FTW; 04.09.2011
comment
Не совсем уверен, что вы имеете в виду. У обычного суффикса trie такого не было бы. Вы уверены, что делаете то, что должны делать? - person Brian Roach; 04.09.2011

Два решения: либо вы строите более легкую структуру (список массивов и набор хэшей для каждого режима — это много), либо, если это ваше лучшее решение, вы используете параметры командной строки -mx и -ms для джема, в котором работают ваши программы.

person Snicolas    schedule 04.09.2011