Алгоритм перестановок без повторения?
в программе, которую я делаю, которая генерирует анаграммы для данного набора букв, мой текущий подход:
- получить все комбинации всех букв
- получить перестановки каждой группы комбинаций
- сортировка полученных перестановок по алфавиту
- удалить дубликаты записей
мой вопрос относится к математике перестановок. Мне интересно, можно ли точно рассчитать размер массива, необходимый для хранения всех оставшихся записей после удаления дубликатов записей (используя, скажем, количество повторяющихся букв в сочетании с формулой перестановки или что-то еще).
Я прошу прощения за неопределенность моего вопроса, я все еще исследую больше комбинаций и перестановок. Я постараюсь развить свою цель, поскольку мое понимание комбинаций и перестановок расширяется, и как только я снова ознакомлюсь с моей программой (это было свободное время мой проект прошлым летом).
2 ответов
если у вас n
элементов, и a[0]
дубликаты одного элемента, a[1]
дубликаты другого элемента, и так далее до a[k]
, тогда общее количество различных перестановок (до дубликатов) составляет n!/(a[0]! a[1]! ... a[k]!)
.
FYI, если вам интересно, с гуавы вы могли бы написать
Collection<List<Character>> uniquePermutations =
Collections2.orderedPermutations(Lists.charactersOf(string));
и результатом будет уникальный перестановки символов, учет дубликатов и все такое. Вы могли бы даже назвать его .size()
метод -- или просто посмотрите на его реализацию для подсказок. (Раскрытие: я вношу свой вклад в гуаву.)
генерирование всех перестановок-действительно плохая идея.Например, слово "переполнение" имеет 40320 перестановок. Таким образом, потребление памяти становится очень высоким по мере роста длины вашего слова.
Я считаю, что проблема, которую вы пытаетесь решить, может быть сведена к выяснению, является ли одно слово анаграммой другого.
затем вы можете решить его, подсчитав, сколько раз каждая буква происходит (это будет 26-кортеж) и сравнивая эти кортежи друг с другом.