Работа с огромными текстовыми файлами в Java - PullRequest
6 голосов
/ 01 августа 2010

Мой учитель дал мне словарь английского языка.

Выберите случайный алфавит, скажите 'a' Напишите слово из алфавита, скажите 'apple' Возьмите последнее слово 'e'Напишите слово от e, скажем, elephant Теперь от 't' и т. Д. Повторение не допускается

Составьте список из 500 слов.Отправьте список по почте учителю.:)

Так что вместо того, чтобы делать это самостоятельно, я работаю над кодом Java, который сделает мою домашнюю работу за меня.Код кажется простым.

Суть алгоритма: выбрать случайное слово из словаря, которое удовлетворяет требованию.искать () с RandomAccessFile.Попробуйте поместить его в набор с упорядочением (может быть, LinkedHashSet)

Но проблема в огромном размере словаря с 300 000+ записей.: |Случайные алгоритмы грубой силы не сработают.

Что может быть лучшим, самым быстрым и наиболее эффективным выходом?

**** ОБНОВЛЕНИЕ: ** Теперь, когда я написал код и его работу,Как я могу сделать его эффективным, чтобы он выбирал общие слова?Любые текстовые файлы, содержащие список общих слов вокруг ?? **

Ответы [ 6 ]

4 голосов
/ 01 августа 2010

Либо ищите структуру данных, позволяющую хранить сжатый словарь в памяти, либо просто выделите процессу больше памяти.Триста тысяч слов - это не так много.

1 голос
/ 01 августа 2010

Надеюсь, это не испортит вам веселье или что-то в этом роде, но на вашем месте я бы воспользовался этим подходом ..

Псевдо-Java:

abstract class Word {
    String word;
    char last();
    char first();         
}

abstract class DynamicDictionary {
    Map<Character,Set<Word>> first_indexed;

    Word removeNext(Word word){
        Set<Word> candidates = first_indexed.get(word.last());
        return removeRandom(candidates);
    }

    /**
     * Remove a random word out from the entire dic.
     */
     Word removeRandom();

    /**
     * Remove and return a random word out from the set provided.
     */
     Word removeRandom(Set<Word> wordset);    
}

, а затем

Word primer = dynamicDictionary.removeRandom();
List<Word> list = new ArrayList<Word>(500);
list.add(primer);
for(int i=0, Word cur = primer;i<499;i++){
    cur = dynamicDictionary.removeNext(cur);
    list.add(cur);
}

ПРИМЕЧАНИЕ. Не предназначен для использования в качестве фактического Java-кода, это просто способ приблизительного объяснения подхода (нет обработки ошибок, нет хорошей структуры классов, если она действительно использовалась, нет инкапсуляции и т. Д. И т. Д.)

Если у меня возникнут проблемы с памятью, возможно, я сделаю это:

abstract class Word {
    int lineNumber;
    char last();
    char first();
}

Если этого недостаточно, угадайте, я воспользуюсь двоичным поиском по файлу или положу его в БДи т.д ..

0 голосов
/ 01 августа 2010

Вот несколько списков частот слов: http://www.robwaring.org/vocab/wordlists/vocfreq.html

Этот текстовый файл, доступный по вышеуказанной ссылке, содержит первые 2000 слов, которые используются наиболее часто: http://www.robwaring.org/vocab/wordlists/1-2000.txt

0 голосов
/ 01 августа 2010

Если я сделаю это:

class LoadWords {
  public static void main(String... args) {
    try {
      Scanner s = new Scanner(new File("/usr/share/dict/words"));
      ArrayList<String> ss = new ArrayList<String>();
      while (s.hasNextLine())
        ss.add(s.nextLine());
      System.out.format("Read %d words\n", ss.size());
    } catch (FileNotFoundException e) {
      e.printStackTrace(System.err);
    }
  }
}

Я могу запустить его с java -mx16m LoadWords, что ограничивает размер кучи Java до 16 Мб, что не так много памяти для Java.В моем файле /usr/share/dict/words содержится примерно 250 000 слов, поэтому он может быть немного меньше вашего.

Вам потребуется использовать структуру данных, отличную от простой ArrayList<String>, которую я использовал.Возможно, HashMap из ArrayList<String>, введенный с начальной буквы слова, будет хорошим начальным выбором.

0 голосов
/ 01 августа 2010

Цель состоит в том, чтобы увеличить ваш словарь английского языка - не увеличивать вашего компьютера словарь английского языка.

Если вы не разделяете эту цель, почемуВы (или ваши родители) платите за обучение?

0 голосов
/ 01 августа 2010

Я думаю, что для этого можно было бы использовать TreeSet, где вы помещаете весь словарь, а затем используете метод subSet, чтобы получить все слова, начинающиеся с нужной буквы, и сделать случайное число в подмножестве. 1003 *

Но, на мой взгляд, лучший способ сделать это из-за количества данных - использовать базу данных с запросами SQL вместо Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...