Поскольку вы говорите «математическое множество», я предполагаю, что вы имеете в виду, что дубликатов нет.
Наивная реализация, которая работает до 32 элементов:
my $set = [1,2,3];
my @subsets;
for my $count ( 1..(1<<@$set)-2 ) {
push @subsets, [ map $count & (1<<$_) ? $set->[$_] : (), 0..$#$set ];
}
(Для полного диапазона поднаборов цикл от 0 до (1 << @ $ set) -1; исключение 0 исключает нулевой набор, исключая (1 << @ $ set) -1 исключает исходный набор.) </p>
Обновление: я не защищаю это использование модуля, просто предлагаю его на тот случай, если вы хотите понять, как решить эту проблему. В общем, каждый элемент либо включен, либо исключен из любого данного подмножества. Вы хотите выбрать элемент и сгенерировать сначала все возможные подмножества других элементов, не включая выбранный элемент, а затем все возможные подмножества других элементов, включая выбранный элемент. Рекурсивно примените это к «генерации всех возможных подмножеств». Наконец, отбросьте нулевое подмножество и неправильное подмножество. В приведенном выше коде каждому элементу назначается бит. Сначала все подмножества
генерируются с включенным старшим битом, затем все те, у кого он выключен. Для каждой из этих альтернатив подмножества генерируются сначала с выключенным битом, следующим за старшим, а затем включенным. Продолжая это до тех пор, пока вы просто не работаете с младшим битом, вы получите все возможные числа по порядку.