Получение предыдущего объекта — различия между версиями
Flanir (обсуждение | вклад) (→Специализация алгоритма для генерации предыдущей мультиперестановки) |
Flanir (обсуждение | вклад) |
||
Строка 13: | Строка 13: | ||
* Вместо <tex>1</tex> записываем <tex>0</tex> | * Вместо <tex>1</tex> записываем <tex>0</tex> | ||
* Дописываем максимально возможный хвост из единиц | * Дописываем максимально возможный хвост из единиц | ||
− | '''int[]''' | + | '''int[]''' prevVector('''int[]''' a): <font color=green>// <tex>n</tex> {{---}} длина вектора</font> |
'''while''' (n >= 0) '''and''' (a[n] != 1) | '''while''' (n >= 0) '''and''' (a[n] != 1) | ||
a[n] = 1 | a[n] = 1 | ||
Строка 28: | Строка 28: | ||
* Перевернем правую часть | * Перевернем правую часть | ||
− | '''int[]''' | + | '''int[]''' prevPermutation('''int[]''' a): <font color=green>// <tex>n</tex> {{---}} длина перестановки</font> |
'''for''' i = n - 2 '''downto''' 0 | '''for''' i = n - 2 '''downto''' 0 | ||
'''if''' a[i] > a[i + 1] | '''if''' a[i] > a[i + 1] | ||
Строка 45: | Строка 45: | ||
* Перевернем правую часть | * Перевернем правую часть | ||
− | '''int[]''' | + | '''int[]''' prevMultipermutation('''int[]''' a): <font color=green>// <tex>n</tex> {{---}} длина перестановки</font> |
'''for''' i = n - 2 '''downto''' 0 | '''for''' i = n - 2 '''downto''' 0 | ||
'''if''' a[i] > a[i + 1] | '''if''' a[i] > a[i + 1] | ||
Строка 64: | Строка 64: | ||
Пусть массив <tex>a</tex> хранит сочетания, так что первый элемент хранится в <tex>a[1]</tex> | Пусть массив <tex>a</tex> хранит сочетания, так что первый элемент хранится в <tex>a[1]</tex> | ||
− | int[] | + | int[] prevChoose('''int[]''' a): <font color=green>// <tex>n</tex> {{---}} количество различных элементов</font> |
a[0] = 0 <font color=green>// <tex>k</tex> {{---}} длина сочетания</font> | a[0] = 0 <font color=green>// <tex>k</tex> {{---}} длина сочетания</font> | ||
for i = k downto 1 | for i = k downto 1 |
Версия 11:56, 30 декабря 2014
Содержание
Алгоритм
Определение: |
Получение предыдущего объекта — это нахождение объекта, предшествующего данному в лексикографическом порядке. |
Объект
называется предыдущим за , если и не найдется такого , что .Отсюда понятен алгоритм:
- Находим суффикс минимальной длины, который можно изменить без изменения префикса текущего объекта
- К оставшейся части дописываем максимально возможный элемент (чтобы было выполнено правило )
- Дописываем максимально возможный хвост
По построению получаем, что
— минимально возможный.Специализация алгоритма для генерации предыдущего битового вектора
- Находим минимальный суффикс, в котором есть , его можно уменьшить, не изменяя оставшейся части
- Вместо записываем
- Дописываем максимально возможный хвост из единиц
int[] prevVector(int[] a): //
— длина вектора
while (n >= 0) and (a[n] != 1)
a[n] = 1
n--
if n == -1
return null
a[n] = 0
return a
Приведённый алгоритм эквивалентен вычитанию единицы из битового вектора.
Специализация алгоритма для генерации предыдущей перестановки
- Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность
- Меняем его с максимальным элементом, меньшим нашего, стоящим правее
- Перевернем правую часть
int[] prevPermutation(int[] a): //
— длина перестановки
for i = n - 2 downto 0
if a[i] > a[i + 1]
max = i + 1
for j = i + 1 to n - 1
if (a[j] < a[max]) and (a[j] < a[i])
max = j
swap(a[i], a[j])
reverse(a, i + 1, n - 1)
return a
return null
Специализация алгоритма для генерации предыдущей мультиперестановки
Алгоритм полностью аналогичен генерации предыдущей перестановки
- Двигаясь справа налево, находим элемент, нарушающий убывающую последовательность
- Меняем его с максимальным элементом, меньшим нашего, стоящим правее
- Перевернем правую часть
int[] prevMultipermutation(int[] a): //
— длина перестановки
for i = n - 2 downto 0
if a[i] > a[i + 1]
max = i + 1
for j = i + 1 to n - 1
if (a[j] < a[max]) and (a[j] < a[i])
max = j
swap(a[i], a[j])
reverse(a, i + 1, n - 1)
return a
return null
Специализация алгоритма для генерации предыдущего сочетания
- находим элемент , так чтобы его разница со следующим отличалась более чем на единицу
- уменьшаем его на единицу
- дописываем максимально возможный хвост
Если элемента
не существует, значит было дано первое сочетание. А значит и предыдущего сочетания не существует.Пусть массив
хранит сочетания, так что первый элемент хранится вint[] prevChoose(int[] a): //— количество различных элементов a[0] = 0 // — длина сочетания for i = k downto 1 if a[i] - a[i - 1] > 1 a[i]-- t = max(a[i] + 1, n - (k - i) + 1) for j = i + 1 to k a[j] = t t++ return a return null