|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Andrey Sapozhnikov 2:5020/400 16 Feb 2002 19:20:40 To : Soft Subject : Re: Такая сложная задача ;) --------------------------------------------------------------------------------
Soft wrote:
> Доброго времени суток, уважаеммый(ая) All
>
> Вот у меня переменная вида "слово1_слово2_слово3". Причем количество "слово"
> может быть любым. еобходимо добавить в массив все комбинации из слов
> 1-3(менять местами всвозможно) плюс количество разное проверять. апример из
> вышеуказанного примера в массиве должны быть созданы следующие значения:
> слово1
> слово2
> слово3
> слово1_слово2
> слово2_слово1
> слово1_слово3
> слово3_слово1
> слово1_слово2_слово3
> слово1_слово3_слово2
> слово2_слово1_слово3 итд
> Долго мозги ломал, но что-то ничего не лезет туда.
Плохо ломал. Задача довольно простая.
# combine($depth, @array)
# Рекурсивная функция возвращающая все комбинации длиной $depth+1 элементов,
# из набора элементов @array. Принцип тривиален - выбираем в качестве первого
# элемента по очереди каждый изнаходящихся в @array, и вызываем combine с
# $depth на 1 меньше и набором элементов из которых исключен выбраный. Это
# дает нам все возможные комбинации меньшей на 1 длины которые могут следовать
# за выбраным элементом.
sub combine {
my $depth = shift;
my @result;
foreach (0..$#_) {
my $word = $_[$_];
push @result, $depth ? map { unshift @$_, $word; $_ }
combine($depth - 1, @_[0..$_-1, $_+1..$#_]) : [$word];
}
@result;
}
# combine_vary(@array)
# Рекуррентная функция вызавающая combine последовательно для
# нахождения цепочек всех возможных длин от 1 до N, где N -
# число элементов в наборе.
sub combine_vary {
map { combine($_, @_) } 0..$#_;
}
# Просто тестовая строка.
my $line = 'word1_word2_word3_word4';
# Приобразуем идиотский список-в-скаляре, в список. (BTW, Вы знаете
# о существовании списков в Перл?)
my @words = split /_/, $line;
# Вызываем combine_vary и для каждой найденой комбинации осуществляем
# обратное преобразование в идиотский скаляр и вывод на печать.
foreach (combine_vary(@words)) {
print join ('_', @$_), "\n";
}
Андрей
--- ifmail v.2.15dev5
* Origin: Demos online service (2:5020/400)
Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/528445294563.html, оценка из 5, голосов 10
|