Рекурсивный всегда требует некоторых умственных усилий для поддержания. А для больших чисел факториал легко становится огромным, и переполнение стека легко может стать проблемой.
Для небольших чисел (3 или 4, что чаще всего встречается) несколько циклов довольно просты и понятны. К сожалению, ответы с циклами не получили голосования.
Начнем с перечисления (а не перестановки). Просто прочтите этот код как псевдо-код Perl.
$foreach $i1 in @list
$foreach $i2 in @list
$foreach $i3 in @list
print "$i1, $i2, $i3\n"
Перечисление встречается чаще, чем перестановка, но если перестановка необходима, просто добавьте условия:
$foreach $i1 in @list
$foreach $i2 in @list
$if $i2==$i1
next
$foreach $i3 in @list
$if $i3==$i1 or $i3==$i2
next
print "$i1, $i2, $i3\n"
Теперь, если вам действительно нужен общий метод потенциально для больших списков, мы можем использовать метод radix. Сначала рассмотрим проблему перечисления:
$n=@list
my @radix
$for $i=0:$n
$radix[$i]=0
$while 1
my @temp
$for $i=0:$n
push @temp, $list[$radix[$i]]
print join(", ", @temp), "\n"
$call radix_increment
subcode: radix_increment
$i=0
$while 1
$radix[$i]++
$if $radix[$i]==$n
$radix[$i]=0
$i++
$else
last
$if $i>=$n
last
Приращение по основанию - это, по сути, подсчет чисел (на основе количества элементов списка).
Теперь, если вам нужна перестановка, просто добавьте проверки внутри цикла:
subcode: check_permutation
my @check
my $flag_dup=0
$for $i=0:$n
$check[$radix[$i]]++
$if $check[$radix[$i]]>1
$flag_dup=1
last
$if $flag_dup
next
Изменить: приведенный выше код должен работать, но для перестановки radix_increment может быть расточительным. Итак, если время имеет практическое значение, мы должны изменить radix_increment на permute_inc:
subcode: permute_init
$for $i=0:$n
$radix[$i]=$i
subcode: permute_inc
$max=-1
$for $i=$n:0
$if $max<$radix[$i]
$max=$radix[$i]
$else
$for $j=$n:0
$if $radix[$j]>$radix[$i]
$call swap, $radix[$i], $radix[$j]
break
$j=$i+1
$k=$n-1
$while $j<$k
$call swap, $radix[$j], $radix[$k]
$j++
$k--
break
$if $i<0
break
Конечно, теперь этот код логически более сложен, я оставлю для читателя упражнения.
person
Hui Zhou
schedule
27.04.2014