Каталог решений - Функция для получения возможных перестановок или комбинаторика для 1С-нега

Функция для получения возможных перестановок или комбинаторика для 1С-нега

Функция для получения возможных перестановок или комбинаторика для 1С-нега

В наличии

Функция, возвращающая массив всех возможных перестановок произвольного множества, состоящих из заданного количества элементов. С повторениями элементов или без.

Категория:

Описание

Понадобилось (не спрашивайте зачем) найти и проанализировать все возможные комбинации элементов массива произвольной длины. Задача хрестоматийная. Так как число возможных элементов и длина комбинации на этапе постановки задачи не определены, напрашивается рекурсивное решение. И что же я нахожу по теме? Ничего для 1С, но множество всяких разных реализаций на Сях, Дельфях и даже VBA.

Что ж, думаю — надо переводить. Перевел на 1С. Но нужно было, чтобы без повторений одного и того же элемента результирующие комбинации были. Начал дописывать и править. В итоге от первоначального алгоритма не осталось ничего, а сама реализация стала короче, чем предлагалась на С, да еще и с дополнительной опцией без повторов элеметов в возможных комбинациях.

Погордился собой минут 20 и решил поделиться с сообществом. Может, кому-нибудь пригодится, и будет моей карме лишний лайк:)

Сама функция:

//мЭлементов 		- массив произвольных элементов, образующих комбинации. Произвольный.
//ДлинаПерестановки	- количество элементов в комбинации. Целое.
//БезПовторов		- признак необходимости получать в результате комбинации в которых один и тот же элемент мЭлементов встречался бы не чаще 1 раза. Булево. По умолчанию - Ложь.

Функция Перестановки(мЭлементов, ДлинаПерестановки, БезПовторов = Ложь, Основание = Неопределено, мРезультата = Неопределено, ТекУровень = 0) Экспорт
	
	Если Основание = Неопределено Тогда Основание = Новый Массив КонецЕсли;
	Если мРезультата = Неопределено Тогда мРезультата = Новый Массив КонецЕсли;
	
	Если ТекУровень < ДлинаПерестановки - 1 Тогда		
		Для Каждого Элемент Из мЭлементов Цикл	
			Если БезПовторов И НЕ Основание.Найти(Элемент) = Неопределено Тогда
			Иначе
				Основание.Добавить(Элемент);
				мРезультата = Перестановки(мЭлементов, ДлинаПерестановки, БезПовторов, Основание, мРезультата, ТекУровень + 1);
				Основание.Удалить(Основание.Количество() - 1);
			КонецЕсли;
		КонецЦикла;
	Иначе
		Для Каждого Элемент Из мЭлементов Цикл
			Если БезПовторов И НЕ Основание.Найти(Элемент) = Неопределено Тогда
			Иначе
				Основание.Добавить(Элемент);
				мРезультата.Добавить(Новый ФиксированныйМассив(Основание));
				Основание.Удалить(Основание.Количество()-1);
			КонецЕсли;
		КонецЦикла;	
	КонецЕсли;	
	Возврат мРезультата;	
КонецФункции

По аргументам все, надеюсь, понятно из описания. По результатам: на выходе получаем массив из фиксированных массивов. Фиксированный массив — возможная комбинация, а количество элементов результирующего массива и есть количество найденных (возможных) комбинаций. Каждый фиксированный массив состоит из ДлинаПерестановки элементов массива мЭлементов — то есть какой-то набор элементов первоначального множества значений. Или одна из возможных комбинаций.

Очевидная вещь, но все таки предупрежу. Если ДлинаПерестановки в аргументах будет больше числа элементов в массиве мЭлементов, а условие уникальности при этом будет Истина, в результате Вы получите замечательный, но пустой массив результатов. Почему? Да потому, что нельзя собрать из Х возможных  элементов комбинацию длиной в Y, не повторяясь, если X<Y. Допустим, в 11 разрядном десятичном числе как минимум одна из цифр должна повториться дважды. Вот как-то так получается:)

Всё!

P.S. Предвидя возмущения широкой общественности по поводу «нафига нам честным, умным, скромным и обычным 1С-негам это нужно» вспомнил одну  публикацию по теме, как помочь бухгалтеру найти, какие же из возможных чисел образуют в сумме ошибку. Вот Вам и готовая сфера применения функции. И при этом используется настоящий, выдержанный и марочный 1С, а не Java:)

has been added to your cart:
Оформление заказа