Надеюсь, это не испортит вам веселье или что-то в этом роде, но на вашем месте я бы воспользовался этим подходом ..
Псевдо-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();
}
Если этого недостаточно, угадайте, я воспользуюсь двоичным поиском по файлу или положу его в БДи т.д ..