Реализации алгоритмов/Алгоритм Нарайаны: различия между версиями
Содержимое удалено Содержимое добавлено
Исправление форматирования, поправки к коду |
|||
Строка 4: | Строка 4: | ||
Во всех приведенных ниже реализациях <code>a</code> — массив, в котором в прямом порядке записана перестановка, а <code>n</code> — количество элементов в перестановке. |
Во всех приведенных ниже реализациях <code>a</code> — массив, в котором в прямом порядке записана перестановка, а <code>n</code> — количество элементов в перестановке. |
||
==[[w:C (язык программирования)|C]]== |
|||
== C == |
|||
<source lang="cpp"> |
<source lang="cpp"> |
||
typedef int T; |
|||
int NarayanaNextPerm (int *a, int n) |
|||
{ |
|||
int i, j, l; |
|||
void swapItems (T *array, unsigned index_1, unsigned index_2) { |
|||
//Шаг 1 |
|||
T temp = array[index_1]; |
|||
for (j = n - 2; j >= 0 && a[j] >= a[j + 1]; j--); |
|||
array[index_1] = array[index_2]; |
|||
array[index_2] = temp; |
|||
} |
|||
int NarayanaNextPermutation (T *a, int n) { |
|||
//Шаг 2 |
|||
int i, j, l; |
|||
/* Шаг № 1 */ |
|||
for (j = n - 2; j >= 0 && a[j] >= a[j + 1]; --j); |
|||
/* Шаг № 2 */ |
|||
if (j == -1) |
if (j == -1) |
||
return 0; |
return 0; |
||
for (l = n - 1; a[j] >= a[l]; --l); |
|||
swapItems(a, l, j); |
|||
++j; |
|||
/* Шаг № 3 */ |
|||
swap(&a[l], &a[j]); |
|||
for (i = 0; i < (n - j + 1) >> 1; ++i) |
|||
swapItems(a, j + i, n - i - 1); |
|||
j++; |
|||
//Шаг 3 |
|||
for (i = 0; i < (n - j + 1) / 2; i++) |
|||
swap(&a[j + i], &a[n - i - 1]); |
|||
return j; |
return j; |
||
} |
} |
||
</source> |
</source> |
||
== |
==[[w:Паскаль (язык программирования)|Pascal]]== |
||
<source lang="pascal"> |
<source lang="pascal"> |
||
type T = integer; |
|||
function NarayanaNextPerm(var a: array of integer; n: integer): integer; |
|||
var |
|||
function NarayanaNextPermutation (var a: array of T; n: integer): integer; |
|||
var i, k, l: integer; |
|||
procedure SwapItems (index_1, index_2: word); |
|||
var temp: T; |
|||
begin |
|||
temp := a[index_1]; |
|||
a[index_1] := a[index_2]; |
|||
a[index_2] := temp |
|||
end; |
|||
begin |
begin |
||
{ Шаг № 1 } |
|||
k := n - 2; |
k := n - 2; |
||
while (k >= 0) and (a[k] >= a[k+1]) do |
while (k >= 0) and (a[k] >= a[k + 1]) do |
||
k := k - 1; |
k := k - 1; |
||
if k = -1 then |
|||
NarayanaNextPermutation := 0 |
|||
if k = -1 then begin |
|||
else |
|||
NarayanaNextPerm := 0; |
|||
begin |
|||
{ Шаг № 2 } |
|||
end; |
|||
l := n - 1; |
|||
while (l >= k + 1) and (a[k] >= a[l]) do |
|||
//Шаг 2 |
|||
l := l - 1; |
|||
SwapItems(k, l); |
|||
{ Шаг № 3 } |
|||
for i := k + 1 to (n + k) div 2 do |
|||
tmp := a[k]; |
|||
begin |
|||
l := n + k - i; |
|||
SwapItems(i, l) |
|||
end; |
|||
//Шаг 3 |
|||
NarayanaNextPermutation := i |
|||
for i := k + 1 to (n + k) div 2 do begin |
|||
end |
|||
tmp := a[i]; |
|||
a[i] := a[t]; |
|||
a[t] := tmp; |
|||
end; |
|||
NarayanaNextPerm := i; |
|||
end; |
end; |
||
</source> |
</source> |
||
== |
==[[w:PHP|PHP]]== |
||
===Вариант № 1=== |
|||
<source lang="PHP"> |
<source lang="PHP"> |
||
function |
function NarayanaNextPermutation ($a, $n) { |
||
$out = $a; |
|||
{ |
|||
// Шаг № 1 |
|||
$k |
$k = $n - 2; |
||
while ($k >= 0 && $out[$k] >= $out[$k + 1]) |
while ($k >= 0 && $out[$k] >= $out[$k + 1]) { |
||
--$k; |
|||
$k--; |
|||
} |
} |
||
if (-1 == $k) { |
|||
return false; |
|||
{ |
|||
return false; |
|||
} |
} |
||
// Шаг № 2 |
|||
$t = $n - 1; |
$t = $n - 1; |
||
while ($t >= 0 && $t >= $k + 1 && $out[$k] >= $out[$t]) |
while ($t >= 0 && $t >= $k + 1 && $out[$k] >= $out[$t]) { |
||
--$t; |
|||
$t--; |
|||
} |
} |
||
$tmp = $out[$k]; |
|||
$tmp = $out[$k]; |
|||
$out[$k] = $out[$t]; |
$out[$k] = $out[$t]; |
||
$out[$t] = $tmp; |
$out[$t] = $tmp; |
||
// Шаг № 3 |
|||
for ($i = $k + 1; $i < ceil(($n + $k) / 2); ++$i) { |
|||
//Шаг 3 |
|||
$t = $n + $k - $i; |
|||
$tmp = $out[$i]; |
|||
{ |
|||
$out[$i] = $out[$t]; |
|||
$out[$t] = $tmp; |
|||
$out[$i] = $out[$t]; |
|||
$out[$t] = $tmp; |
|||
} |
} |
||
Строка 105: | Строка 102: | ||
</source> |
</source> |
||
===Вариант № 2=== |
|||
{{BookCat}} |
|||
=== PHP === |
|||
Вариант с выводом справа налево: |
Вариант с выводом справа налево: |
||
<source lang="PHP"> |
<source lang="PHP"> |
||
$b="123456789"; |
$b = "123456789"; |
||
$a=strrev($b); |
$a = strrev($b); |
||
while ($a !=$b) { |
while ($a !=$b) { |
||
$i=0; |
$i = 0; |
||
while($a[$i] > $a[$i-1]) { |
while($a[$i] > $a[$i - 1]) { |
||
$i++; |
$i++; |
||
} |
|||
} |
|||
$j=0; |
$j = 0; |
||
while($a[$j] < $a[$i]) { |
while($a[$j] < $a[$i]) { |
||
++$j; |
|||
} |
|||
$c = $a[$j]; |
|||
$j++; |
|||
$a[$j] = $a[$i]; |
|||
} |
|||
$a[$i] = $c; |
|||
$x = strrev(substr($a, 0, $i)); |
|||
$c=$a[$j]; |
|||
$ |
$y = substr($a, $i); |
||
$a[$i]=$c; |
|||
$x=strrev(substr($a, 0, $i)); |
|||
$y=substr($a, $i); |
|||
print $a=$x.$y; |
|||
print ‘<br/>’; |
|||
print $a = $x . $y; |
|||
print ‘<br/>’; |
|||
} |
} |
||
</source> |
</source> |
||
{{BookCat}} |
Версия от 15:48, 23 апреля 2017
Алгори́тм Нарайа́ны — нерекурсивный алгоритм, генерирующий по данной перестановке следующую за ней в лексикографическом порядке перестановку.
Во всех приведенных ниже реализациях a
— массив, в котором в прямом порядке записана перестановка, а n
— количество элементов в перестановке.
C
typedef int T;
void swapItems (T *array, unsigned index_1, unsigned index_2) {
T temp = array[index_1];
array[index_1] = array[index_2];
array[index_2] = temp;
}
int NarayanaNextPermutation (T *a, int n) {
int i, j, l;
/* Шаг № 1 */
for (j = n - 2; j >= 0 && a[j] >= a[j + 1]; --j);
/* Шаг № 2 */
if (j == -1)
return 0;
for (l = n - 1; a[j] >= a[l]; --l);
swapItems(a, l, j);
++j;
/* Шаг № 3 */
for (i = 0; i < (n - j + 1) >> 1; ++i)
swapItems(a, j + i, n - i - 1);
return j;
}
Pascal
type T = integer;
function NarayanaNextPermutation (var a: array of T; n: integer): integer;
var i, k, l: integer;
procedure SwapItems (index_1, index_2: word);
var temp: T;
begin
temp := a[index_1];
a[index_1] := a[index_2];
a[index_2] := temp
end;
begin
{ Шаг № 1 }
k := n - 2;
while (k >= 0) and (a[k] >= a[k + 1]) do
k := k - 1;
if k = -1 then
NarayanaNextPermutation := 0
else
begin
{ Шаг № 2 }
l := n - 1;
while (l >= k + 1) and (a[k] >= a[l]) do
l := l - 1;
SwapItems(k, l);
{ Шаг № 3 }
for i := k + 1 to (n + k) div 2 do
begin
l := n + k - i;
SwapItems(i, l)
end;
NarayanaNextPermutation := i
end
end;
PHP
Вариант № 1
function NarayanaNextPermutation ($a, $n) {
$out = $a;
// Шаг № 1
$k = $n - 2;
while ($k >= 0 && $out[$k] >= $out[$k + 1]) {
--$k;
}
if (-1 == $k) {
return false;
}
// Шаг № 2
$t = $n - 1;
while ($t >= 0 && $t >= $k + 1 && $out[$k] >= $out[$t]) {
--$t;
}
$tmp = $out[$k];
$out[$k] = $out[$t];
$out[$t] = $tmp;
// Шаг № 3
for ($i = $k + 1; $i < ceil(($n + $k) / 2); ++$i) {
$t = $n + $k - $i;
$tmp = $out[$i];
$out[$i] = $out[$t];
$out[$t] = $tmp;
}
return $out;
}
Вариант № 2
Вариант с выводом справа налево:
$b = "123456789";
$a = strrev($b);
while ($a !=$b) {
$i = 0;
while($a[$i] > $a[$i - 1]) {
$i++;
}
$j = 0;
while($a[$j] < $a[$i]) {
++$j;
}
$c = $a[$j];
$a[$j] = $a[$i];
$a[$i] = $c;
$x = strrev(substr($a, 0, $i));
$y = substr($a, $i);
print $a = $x . $y;
print ‘<br/>’;
}