Получение следующего объекта — различия между версиями
Free0u (обсуждение | вклад) (→Пример работы) |
Free0u (обсуждение | вклад) (→Пример работы) |
||
Строка 58: | Строка 58: | ||
=== Пример работы === | === Пример работы === | ||
{| border="1" | {| border="1" | ||
− | |1||3||2||5||4||исходная перестановка | + | |1||3||style="background:#FFCC00"|2||5||style="background:#FFCC00"|4||исходная перестановка |
|- | |- | ||
| || ||^|| || ||находим элемент, нарушающий убывающую последовательность | | || ||^|| || ||находим элемент, нарушающий убывающую последовательность | ||
Строка 64: | Строка 64: | ||
| || || || ||^||минимальный элемент больше нашего | | || || || ||^||минимальный элемент больше нашего | ||
|- | |- | ||
− | | || ||4||5||2||меняем их местами | + | |1||3||style="background:#FFCC00"|4||5||style="background:#FFCC00"|2||меняем их местами |
|- | |- | ||
− | | || || ||2||5||разворачивам правую часть | + | |1||3||4||style="background:#FFCC00"|2||style="background:#FFCC00"|5||разворачивам правую часть |
|- | |- | ||
− | |1||3||4||2||5||следующая перестановка | + | |'''1'''||'''3'''||'''4'''||'''2'''||'''5'''||следующая перестановка |
|} | |} | ||
Версия 02:29, 30 октября 2011
Содержание
Алгоритм
Определение: |
Получение следующего объекта — это нахождение объекта, следующего за данным в лексикографическом порядке. |
Пусть дан объект
. Назовем объект следующим, если и не найдется такого , что .Отсюда понятен алгоритм:
- Находим минимальный суффикс в объекте , который можно увеличить, не меняя префикс
- К префиксу дописываем минимальный возможный элемент (чтобы было выполнено правило )
- Дописываем минимальный возможный хвост
Специализация алгоритма для генерации следующего битового вектора
Двигаемся справа налево по элементам объекта, пока не найдем элемент 0. Заменим его на 1, а все элементы справа на нули.
bool next_vec(vector<int> &a) { int n = a.size(); int pos = n - 1; while (pos != -1 && a[pos] == 1) --pos; if (pos == -1) return false; a[pos] = 1; while (++pos < n) a[pos] = 0; return true; }
Пример работы
0 | 1 | 0 | 1 | 1 | исходный битовый вектор |
^ | находим элемент 0 (самый правый) | ||||
0 | 1 | 1 | 1 | 1 | меняем его на 1 |
0 | 1 | 1 | 0 | 0 | меняем элементы правее на нули |
0 | 1 | 1 | 0 | 0 | следующий битовый вектор |
Специализация алгоритма для генерации следующей перестановки
Двигаемся справа налево по элементам объекта, пока не найдем элемент, нарушающий убывающую последовательность. Обменяем его с минимальным элементом, большим нашего, стоящим правее. Далее перевернем правую часть.
bool next_permutation(vector<int> &a) { int n = a.size(); int pos = n - 2; while (pos != -1 && a[pos] > a[pos + 1]) --pos; if (pos == -1) return false; int k = n - 1; while (a[pos] > a[k]) --k; swap(a[pos], a[k]); int l = pos + 1, r = n - 1; while (l < r) swap(a[l++], a[r--]); return true; }
Пример работы
1 | 3 | 2 | 5 | 4 | исходная перестановка |
^ | находим элемент, нарушающий убывающую последовательность | ||||
^ | минимальный элемент больше нашего | ||||
1 | 3 | 4 | 5 | 2 | меняем их местами |
1 | 3 | 4 | 2 | 5 | разворачивам правую часть |
1 | 3 | 4 | 2 | 5 | следующая перестановка |