Есть некоторые хорошие ответы уже здесь, и я думаю, что Trie, вероятно, правильный путь, но это интересная проблема, так что я буду бросать в ценности мои два цента ...
В наивный подход состоял бы в том, чтобы сгенерировать все перестановки доступных букв и всех различных подмножеств, а затем искать каждое потенциальное слово в словаре. Проблема в том, что, хотя это не сложно сделать, есть удивительно большое количество потенциальных слов, и большинство из них являются недействительными.
С положительной стороны, проверку словаря можно ускорить с помощью бинарного поиска или чего-то подобного. С отрицательной стороны вы будете делать это столько раз, что программа остановится на длинные списки писем.
Нам определенно необходимо предварительно обработать словарь, чтобы сделать его более полезным, и нам действительно нужно иметь возможность быстро исключить большинство потенциальных совпадений, даже если метод имеет случайные ложные срабатывания.
Один из способов сделать это - представить буквы, которые слово использует в битовой карте. Другими словами, предварительно рассчитайте 32-битное число для каждого слова в словаре, где каждый бит установлен, если соответствующая буква алфавита используется в слове хотя бы один раз. Это позволит вам найти все потенциальные слова, выполнив линейное сканирование словаря и сохранив только те, которые используют только буквы, которые у вас есть. Я подозреваю, что с немного сообразительности и индексации вы можете сделать лучше, чем линейный.
Из выбранных вами кандидатов потребуются больше экземпляров письма, чем у вас есть, поэтому они будут ложными срабатываниями. Это означает, что вам нужно выполнить окончательную проверку всех кандидатов, сгенерированных вами, для устранения почти хитов. Существует много способов сделать это, но одним из самых простых является просмотр списка букв и замена первого появления этой буквы в потенциальном слове тире.Когда вы закончите, если потенциальное слово имеет ничего, кроме тире, это провал. Более элегантное решение, хотя и не обязательно быстрее, было бы создание массива буквенных частот и сравнение их.
Опять же, я думаю, что попытки - это, вероятно, путь, но я надеюсь, что эти идеи полезны для вас.
редактировать
Позвольте мне выбросить пример того, как вы могли бы сделать лучше, чем полный линейный поиск по первоначальному запросу: использовать десятичную. Сохраните простой индекс, который позволяет вам искать первое слово, которое начинается с данной буквы. Затем, выполняя поиск, пропустите все слова, начинающиеся с буквы, которой у вас нет. Это не гигантское ускорение, но это улучшение.
Так что на самом деле вопрос не в том, «как эффективно перебирать вектор», а скорее «как эффективно узнать, может ли какое-либо слово из коллекции быть собрано из набора букв»? – jalf
Вы, кажется, не учитываете в своем описании проблемы, что слова могут быть сформированы как на доске, так и в руке игрока. – jemfinch
Ох. Я не принимал это во внимание. Большая, но еще сложность добавлена к уже (для моего уровня знаний) сложной проблеме –