Алгоритм перестановок
Msg : 1611 из 3560 -1596 +1615 *1614 From : Oleg I. Khovayko 2:5020/400 Срд 23 Авг 00 18:02 To : All Чтв 24 Авг 00 06:21 Subj : Re: перебор вариантов перебора
Задача: Кто знает алгоритм полной перестановки цифр в числе ? Hапример: 123,132,213,231,312,321
Решение
:1. Сначала составим список разрешенных цифр, и сколько этих цифр разрешено. Hапример, если надо создать все возможные перестановки цифр 1,3,3,7 то список будет такой:
- 1 - 1 шт
- 3 - 2 шт
- 7 - 1 шт
2. Очевидно, что в первой (самой левой) позиции синтезированного числа последовательно сменятся все разрешенные цифры из списка. Поэтому для позиции 0 пустим цикл по всем разрешенным цифрам. Hо так как текущая цифра изъята для нашей позиции 0, то еенный "счетчик разрешения" уменьшаем на единицу (а после перехода от этой цифры к следующей - восстанавливаем значение счетчика для текушей цифры и уменьшаем значение счетчика для следующей).
3. Для позиции 1 справедливы все те же рассуждения, что и для позиции 0, посему напрашивается рекурсивный алгоритм следующего вида:
char result[5];
char enabled[] =" 137";
char enabled_cnt[] = { 1, 2, 1 };
generate(char *pos) {
int n;
int printflag = 1;
*pos = 0;
for(n = 0; enabled[n]; n++) {
if(enabled_cnt[n] > 0) {
*pos = enabled[n];
enabled_cnt[n]--;
generate(char pos + 1);
enabled_cnt[n]++;
printflag = 0;
}
}
if(printflag)
printf("%s\n", result);
}
main() {
generate(result);
}
4. WARNING!! Я не проверял этот алгоритм, а просто "с ходу" придумал его и написал в этом письме. Поэтому не факт, что он сразу с ходу заработает. Hо я надеюсь, идея понятна, и до ума этот алгоритм довести особого труда не составит.
Оставить комментарий
Комментарии


program Perest;
{$M 65520,0,655360}
uses crt;
var mas : array[1..10] of byte;
i,N : 1..10;
procedure recurs(num : byte);
var i,j : integer;
procedure change(var a,b : byte);
var c:byte;
begin
c:=a;
a:=b;
b:=c;
end;
begin
if num = N then
begin
for i:=1 to N do
write(mas,' ');
writeln;
end else
for j:=num+1 to N do
begin
Change(mas[num+1], mas[j]);
recurs(num+1);
Change(mas[num+1], mas[j]);
end;
end;
begin
clrscr;
write('The quantity of array''s elements (1..10): ');
readln(N);
for i:=1 to N do
mas:=i;
recurs(0);
readln;
end.
Этот я проверил, так что он точно работает :)
А вот мне интересен нерекурсивный алгоритм, я где-то видел небольшую программку, что выводила на экран все перестановки С(n, k) (C из n по k), и которая была написана всего-лишь в 5 циклов for. Там, вроде, был перевод в другую систему счисления, для чего он нужен- не помню. Если у кого есть этот алгоритм, please, буду очень признателен.
Спасибо за внимание :)


