Реализации алгоритмов/Алгоритм Нарайаны
Алгори́тм Нарайа́ны — нерекурсивный алгоритм, генерирующий по данной перестановке следующую за ней в лексикографическом порядке перестановку.
Алгоритм
[править]Пусть — последовательность из элементов, для которых требуется найти очередную в лексикографическом порядке перестановку.
Алгоритм поиска очередной перестановки для последовательности с неубывающим (невозрастающим) изначальным порядком элементов:
- Найти наибольшее , для которого выполняется условие (). Если такого нет, значит все перестановки были сгенерированы.
- Найти наибольшее , для которого выполняется условие (). Затем поменять местами и .
- Элементы переставить в обратном порядке.
Реализации
[править]В нижеприведённых реализациях sequence
— последовательность из count
элементов, в которой производятся перестановки (как правило — массив из count элементов), compare(x, y)
— функция, которая должна возвращать значение «истина» если x < y
, и «ложь» иначе (если исходный порядок элементов последовательности неубывающий; для невозрастающего исходного порядка условие меняется на x > y
).
Если не оговорено другое, то функция поиска очередной перестановки возвращает значение «истина», если перестановка найдена, либо «ложь», если следующей перестановки не существует (перебор закончен).
' Narayana.vb
Public Module Narayana
''' <summary>
''' Функция, задающая отношение порядка для значений типа T: < либо >
''' </summary>
Public Delegate Function Predicate2(Of T)(ByVal value_0 As T, ByVal value_1 As T) As Boolean
''' <summary>
''' Поиск очередной перестановки
''' </summary>
Public Function NextPermutation(Of T)(ByVal sequence As T(), ByVal compare As Predicate2(Of T)) As Boolean
' Этап № 1
Dim i As Integer = sequence.Length
Do
If i < 2 Then Return False ' Перебор закончен
i -= 1
Loop Until compare(sequence(i - 1), sequence(i))
' Этап № 2
Dim j As Integer = sequence.Length
Do While i < j And Not compare(sequence(i - 1), sequence(j - 1))
j -= 1
Loop
_SwapItems(sequence, i - 1, j - 1)
' Этап № 3
j = sequence.Length
Do While i < j - 1
j -= 1
_SwapItems(sequence, i, j)
i += 1
Loop
Return True
End Function
''' <summary>
''' Обмен значениями двух элементов последовательности
''' </summary>
Private Sub _SwapItems(Of T)(ByVal sequence As T(), ByVal index_0 As Integer, ByVal index_1 As Integer)
Dim item As T = sequence(index_0)
sequence(index_0) = sequence(index_1)
sequence(index_1) = item
End Sub
End Module
Пример использования:
' NarayanaTest.vb
Module NarayanaTest
''' <summary>
''' Возвращает True, если value_0 меньше value_1, иначе — False
''' </summary>
Private Function Less(Of T As IComparable)(ByVal value_0 As T, ByVal value_1 As T) As Boolean
Return value_0.CompareTo(value_1) < 0
End Function
''' <summary>
''' Возвращает True, если value_0 больше value_1, иначе — False
''' </summary>
Private Function Greater(Of T As IComparable)(ByVal value_0 As T, ByVal value_1 As T) As Boolean
Return value_0.CompareTo(value_1) > 0
End Function
''' <summary>
''' Инициализация последовательности
''' </summary>
Private Sub InitSequence(ByVal sequence As Integer())
' Заполнение последовательности значениями 1, 2, 3…
For i As Integer = sequence.Length To 1 Step -1
sequence(i - 1) = i
Next
End Sub
''' <summary>
''' Вывод содержимого последовательности
''' </summary>
Private Sub OutputSequence(Of T)(ByVal sequence As T())
Console.Write("["C)
If sequence IsNot Nothing And sequence.Length > 0 Then
Console.Write(sequence(0))
For i As Integer = 1 To sequence.GetUpperBound(0)
Console.Write(", ")
Console.Write(sequence(i))
Next
End If
Console.WriteLine("]"C)
End Sub
''' <summary>
''' Основная программа
''' </summary>
Public Sub Main(ByVal args As String())
Dim count As Integer = Integer.Parse(Console.ReadLine())
Dim sequence(count - 1) As Integer
InitSequence(sequence) ' Формирование исходной последовательности
Console.WriteLine("Неубывающая последовательность и её перестановки:")
Do
OutputSequence(sequence)
Loop While Narayana.NextPermutation(sequence, AddressOf Less)
' x < y — критерий сравнения для неубывающей последовательности
Console.WriteLine("Невозрастающая последовательность и её перестановки:")
Do
OutputSequence(sequence)
Loop While Narayana.NextPermutation(sequence, AddressOf Greater)
' x > y — критерий сравнения для невозрастающей последовательности
End Sub
End Module
/* narayana.h */
#ifndef _NARAYANA_H_
#define _NARAYANA_H_
typedef int T; /* Вместо int можно подставить любой тип */
/* Обмен значениями двух элементов последовательности */
static void _swapItems(T *sequence, unsigned index_0, unsigned index_1);
/* Поиск очередной перестановки */
unsigned nextPermutation(T *sequence, unsigned const count, int (*compare)(T const, T const));
#endif
/* narayana.c */
#include "narayana.h"
/* Обмен значениями двух элементов последовательности */
static void _swapItems(T *sequence, unsigned index_0, unsigned index_1) {
T item = sequence[index_0];
sequence[index_0] = sequence[index_1];
sequence[index_1] = item;
}
/* Поиск очередной перестановки */
unsigned nextPermutation(T *sequence, unsigned count, int (*compare)(T const, T const)) {
unsigned i = count, j;
/* Этап № 1 */
do {
if (i < 2)
return 0; /* Перебор закончен */
--i;
} while (!(*compare)(sequence[i - 1], sequence[i]));
/* Этап № 2 */
for (j = count; j > i && !(*compare)(sequence[i - 1], sequence[--j]); );
_swapItems(sequence, i - 1, j);
/* Этап № 3 */
for (j = count; i < --j; )
_swapItems(sequence, i++, j);
return 1;
}
Пример использования:
/* narayana_test.c */
#include <malloc.h>
#include <stdio.h>
#include "narayana.h"
/* Возвращает 1, если value_0 меньше value_1, иначе — 0 */
int less(T const value_0, T const value_1) {
return value_0 < value_1;
}
/* Возвращает 1, если value_0 больше value_1, иначе — 0 */
int greater(T const value_0, T const value_1) {
return value_0 > value_1;
}
/* Инициализация последовательности */
void initSequence(T *sequence, unsigned count) {
/* Заполнение последовательности значениями 1, 2, 3… */
unsigned i;
for (i = count; i; --i)
sequence[i - 1] = i;
}
/* Вывод содержимого последовательности */
void outputSequence(T const *sequence, unsigned count) {
putchar('[');
if (count) { /* Если последовательность не пуста */
unsigned i;
printf("%d", sequence[0]);
for (i = 1; i < count; ++i)
printf(", %d", sequence[i]);
}
putchar(']');
putchar('\n');
}
/* Основная программа */
int main() {
unsigned count;
scanf("%d", &count);
T *sequence = (T*)malloc(count * sizeof(T));
initSequence(sequence, count); /* Формирование исходной последовательности */
printf("Неубывающая последовательность и её перестановки:\n");
do {
outputSequence(sequence, count);
} while (nextPermutation(sequence, count, &less));
/* x < y — критерий сравнения для неубывающей последовательности */
printf("Невозрастающая последовательность и её перестановки:\n");
do {
outputSequence(sequence, count);
} while (nextPermutation(sequence, count, &greater));
/* x > y — критерий сравнения для невозрастающей последовательности */
free(sequence);
return 0;
}
На основе итераторов. В качестве последовательности могут выступать не только массивы, но и другие контейнеры, поддерживающие последовательный доступ, например, списки.
// narayana.hpp
#ifndef _NARAYANA_HPP_
#define _NARAYANA_HPP_
namespace Narayana {
// Обмен значениями двух элементов последовательности
template <typename T>
static void _swap(T &variable_0, T &variable_1) {
T variable = variable_0;
variable_0 = variable_1;
variable_1 = variable;
}
// Поиск очередной перестановки
template <typename Iterator, typename T>
bool nextPermutation(Iterator const begin, Iterator const end, bool (*compare)(T const, T const)) {
if (begin == end) // Если последовательность не содержит элементов
return false; // Нечего перебирать
// Этап № 1
Iterator i = end - 1, j = end;
do {
if (i == begin)
return false; // Перебор закончен
} while (!(*compare)(*--i, *--j));
// Этап № 2
j = end;
while (j != i && !(*compare)(*i, *--j));
_swap(*i, *j);
// Этап № 3
++i;
j = end;
for ( ; (i != j) && (i != --j); ++i)
_swap(*i, *j);
return true;
}
}
#endif
Пример использования:
// narayana_test.cpp
#include <iostream>
#include "narayana.hpp"
// Возвращает true, если value_0 меньше value_1, иначе — false
template <typename T>
bool less(T value_0, T value_1) {
return value_0 < value_1;
}
// Возвращает true, если value_0 больше value_1, иначе — false
template <typename T>
bool greater(T value_0, T value_1) {
return value_0 > value_1;
}
// Инициализация последовательности
template <typename Iterator>
void initSequence(Iterator const begin, Iterator const end) {
// Заполнение последовательности значениями 1, 2, 3…
int i = 0;
for (Iterator current = begin; current != end; ++current)
*current = ++i;
}
// Вывод содержимого последовательности
template <typename Iterator>
void outputSequence(Iterator const begin, Iterator const end) {
std::cout << '[';
if (begin != end) {
std::cout << *begin;
for (Iterator current = begin; ++current != end; )
((std::cout << ',') << ' ') << *current;
}
(std::cout << ']') << '\n';
}
// Основная программа
int main() {
unsigned count;
std::cin >> count;
int *sequence = new int[count], *sequence_end = sequence + count;
initSequence(sequence, sequence_end); // Формирование исходной последовательности
std::cout << "Неубывающая последовательность и её перестановки:\n";
do {
outputSequence(sequence, sequence_end);
} while (Narayana::nextPermutation(sequence, sequence_end, &less<int>));
// x < y — критерий сравнения для неубывающей последовательности
std::cout << "Невозрастающая последовательность и её перестановки:\n";
do {
outputSequence(sequence, sequence_end);
} while (Narayana::nextPermutation(sequence, sequence_end, &greater<int>));
// x > y — критерий сравнения для невозрастающей последовательности
delete [] sequence;
return 0;
}
// Narayana.cs
public static class Narayana {
/// <summary>
/// Функция, задающая отношение порядка для значений типа T: < либо >
/// </summary>
public delegate bool Predicate2<T>(T value_0, T value_1);
/// <summary>
/// Поиск очередной перестановки
/// </summary>
public static bool NextPermutation<T>(T[] sequence, Predicate2<T> compare)
{
// Этап № 1
var i = sequence.Length;
do
{
if (i < 2)
return false; // Перебор закончен
--i;
} while (!compare(sequence[i - 1], sequence[i]));
// Этап № 2
var j = sequence.Length;
while (i < j && !compare(sequence[i - 1], sequence[--j]));
_SwapItems(sequence, i - 1, j);
// Этап № 3
j = sequence.Length;
while (i < --j)
_SwapItems(sequence, i++, j);
return true;
}
/// <summary>
/// Обмен значениями двух элементов последовательности
/// </summary>
private static void _SwapItems<T>(T[] sequence, int index_0, int index_1)
{
var item = sequence[index_0];
sequence[index_0] = sequence[index_1];
sequence[index_1] = item;
}
}
Пример использования:
// NarayanaTest.cs
public static class NarayanaTest
{
/// <summary>
/// Возвращает true, если value_0 меньше value_1, иначе — false
/// </summary>
private static bool Less<T>(T value_0, T value_1) where T: System.IComparable
{
return value_0.CompareTo(value_1) < 0;
}
/// <summary>
/// Возвращает true, если value_0 больше value_1, иначе — false
/// </summary>
private static bool Greater<T>(T value_0, T value_1) where T: System.IComparable
{
return value_0.CompareTo(value_1) > 0;
}
/// <summary>
/// Инициализация последовательности
/// </summary>
private static void InitSequence(int[] sequence)
{
// Заполнение последовательности значениями 1, 2, 3…
for (var i = sequence.Length; i > 0; --i)
sequence[i - 1] = i;
}
/// <summary>
/// Вывод содержимого последовательности
/// </summary>
private static void OutputSequence<T>(T[] sequence)
{
System.Console.Write('[');
if (!(sequence == null) && (sequence.Length > 0))
{
System.Console.Write(sequence[0]);
for (var i = 1; i < sequence.Length; ++i)
{
System.Console.Write(", ");
System.Console.Write(sequence[i]);
}
}
System.Console.WriteLine(']');
}
/// <summary>
/// Основная программа
/// </summary>
public static void Main()
{
var count = int.Parse(System.Console.ReadLine());
var sequence = new int[count];
InitSequence(sequence); // Формирование исходной последовательности
System.Console.WriteLine("Неубывающая последовательность и её перестановки:");
do
{
OutputSequence(sequence);
} while (Narayana.NextPermutation(sequence, Less));
// x < y — критерий сравнения для неубывающей последовательности
System.Console.WriteLine("Невозрастающая последовательность и её перестановки:");
do
{
OutputSequence(sequence);
} while (Narayana.NextPermutation(sequence, Greater));
// x > y — критерий сравнения для невозрастающей последовательности
}
}
// narayana/narayana.go
package narayana
type T = int // Вместо int можно подставить любой тип
// Поиск очередной перестановки
func NextPermutation(sequence []T, compare func (T, T) bool) bool {
count := len(sequence)
i := count
// Этап № 1
for {
if i < 2 {
return false // Перебор закончен
}
i--
if compare(sequence[i - 1], sequence[i]) {
break
}
}
// Этап № 2
j := count
for j > i && !compare(sequence[i - 1], sequence[j - 1]) {
j--
}
sequence[i - 1], sequence[j - 1] = sequence[j - 1], sequence[i - 1]
// Этап № 3
j = count
for i < j - 1 {
j--
sequence[i], sequence[j] = sequence[j], sequence[i]
i++
}
return true
}
Пример использования:
// narayana_test.go
package main
import (
"fmt",
"narayana"
)
// Возвращает true, если value_0 меньше value_1, иначе — false
func less(value_0, value_1 narayana.T) bool {
return value_0 < value_1
}
// Возвращает true, если value_0 больше value_1, иначе — false
func greater(value_0, value_1 narayana.T) bool {
return value_0 > value_1
}
// Инициализация последовательности
func initSequence(sequence []narayana.T) {
// Заполнение последовательности значениями 1, 2, 3…
value := narayana.T(len(sequence))
for i := len(sequence); i > 0; {
i--
sequence[i] = value
value--
}
}
// Основная программа
func main() {
var count uint
fmt.Scan(&count)
var sequence := make([]narayana.T, count)
initSequence(sequence) // Формирование исходной последовательности
fmt.Println("Неубывающая последовательность и её перестановки:")
for {
fmt.Println(sequence)
if !narayana.NextPermutation(sequence, less) {
break
}
// x < y — критерий сравнения для неубывающей последовательности
}
fmt.Println("Невозрастающая последовательность и её перестановки:")
for {
fmt.Println(sequence)
if !narayana.NextPermutation(sequence, greater) {
break
}
// x > y — критерий сравнения для невозрастающей последовательности
}
sequence = nil
}
// Narayana.java
abstract class Narayana {
// Функция, задающая отношение порядка для значений типа T: < либо >
@FunctionalInterface
interface Predicate2 <T extends Comparable> {
boolean compare(final T value_0, final T value_1);
}
// Поиск очередной перестановки
public static final <T extends Comparable> boolean nextPermutation(T[] sequence, Predicate2<T> comparator) {
// Этап № 1
int i = sequence.length;
do {
if (i < 2)
return false; // Перебор закончен
--i;
} while (!comparator.compare(sequence[i - 1], sequence[i]));
// Этап № 2
int j = sequence.length;
while (i < j && !comparator.compare(sequence[i - 1], sequence[--j]));
_swapItems(sequence, i - 1, j);
// Этап № 3
j = sequence.length;
while (i < --j)
_swapItems(sequence, i++, j);
return true;
}
// Обмен значениями двух элементов последовательности
private static final <T> void _swapItems(T[] sequence, int index_0, int index_1) {
T temp = sequence[index_0];
sequence[index_0] = sequence[index_1];
sequence[index_1] = temp;
}
}
Пример использования:
// NarayanaTest.java
import java.util.Arrays;
import java.util.Scanner;
public class NarayanaTest {
// Возвращает true, если value_0 меньше value_1, иначе — false
static final <T extends Comparable> boolean less(final T value_0, final T value_1) {
return value_0.compareTo(value_1) < 0;
}
// Возвращает true, если value_0 больше value_1, иначе — false
static final <T extends Comparable> boolean greater(final T value_0, final T value_1) {
return value_0.compareTo(value_1) > 0;
}
// Инициализация последовательности
static final void initSequence(Integer[] sequence) {
// Заполнение последовательности значениями 1, 2, 3…
for (int value = sequence.length; value > 0; --value)
sequence[value - 1] = value;
}
// Основная программа
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int count = scanner.nextInt();
Integer[] sequence = new Integer[count];
initSequence(sequence); // Формирование исходной последовательности
System.out.println("Неубывающая последовательность и её перестановки:");
do {
System.out.println(Arrays.deepToString(sequence));
} while (Narayana.nextPermutation(sequence, NarayanaTest::less));
// x < y — критерий сравнения для неубывающей последовательности
System.out.println("Невозрастающая последовательность и её перестановки:");
do {
System.out.println(Arrays.deepToString(sequence));
} while (Narayana.nextPermutation(sequence, NarayanaTest::greater));
// x > y — критерий сравнения для невозрастающей последовательности
}
}
{ Narayana.pas }
UNIT Narayana;
INTERFACE
type T = Integer; { Вместо Integer можно использовать любой тип }
{ Функция, задающая отношение порядка для значений типа T: < либо > }
TPredicate2 = function(const value_0, value_1: T): Boolean;
{ Поиск очередной перестановки }
function NextPermutation(var sequence: array of T; Compare: TPredicate2): Boolean;
IMPLEMENTATION
{ Поиск очередной перестановки }
function NextPermutation(var sequence: array of T; Compare: TPredicate2): Boolean;
var count, i, j: Word;
{ Обмен значениями двух элементов последовательности }
procedure SwapItems(index_1, index_2: Word);
var item: T;
begin
item := sequence[index_1];
sequence[index_1] := sequence[index_2];
sequence[index_2] := item
end;
begin
count := Length(sequence);
{ Этап № 1 }
i := count;
repeat
if i < 2 then
begin
NextPermutation := false;
Exit
{ Перебор закончен }
end;
i := i - 1
until Compare(sequence[i - 1], sequence[i]);
{ Этап № 2 }
j := count;
while (j > i) and not Compare(sequence[i - 1], sequence[j - 1]) do
j := j - 1;
SwapItems(i - 1, j - 1);
{ Этап № 3 }
j := count;
while i < j - 1 do
begin
j := j - 1;
SwapItems(i, j);
i := i + 1
end;
NextPermutation := true
end;
END.
Пример использования:
{ NarayanaTest.pas }
PROGRAM NarayanaTest;
USES Narayana;
VAR sequence: array of T;
count: Word;
{ Возвращает true, если value_0 меньше value_1, иначе — false }
function Less(const value_0, value_1: T): Boolean;
begin
Less := value_0 < value_1
end;
{ Возвращает true, если value_0 больше value_1, иначе — false }
function Greater(const value_0, value_1: T): Boolean;
begin
Greater := value_0 > value_1
end;
{ Инициализация последовательности }
procedure InitSequence(var sequence: array of T);
var i: Word;
begin
{ Заполнение последовательности значениями 1, 2, 3… }
for i := Length(sequence) downTo 1 do
sequence[i - 1] := i;
end;
{ Вывод содержимого последовательности }
procedure OutputSequence(const sequence: array of T);
var i, count: Word;
begin
Write('[');
count := Length(sequence);
if count > 0 then { Если последовательность не пуста }
begin
Write(sequence[0]);
for i := 1 to count - 1 do
Write(', ', sequence[i])
end;
WriteLn(']')
end;
{ Основная программа }
BEGIN
ReadLn(count);
SetLength(sequence, count);
InitSequence(sequence); { Формирование исходной последовательности }
WriteLn('Неубывающая последовательность и её перестановки:');
repeat
OutputSequence(sequence)
until not NextPermutation(sequence, @Less);
{ x < y — критерий сравнения для неубывающей последовательности }
WriteLn('Невозрастающая последовательность и её перестановки:');
repeat
OutputSequence(sequence)
until not NextPermutation(sequence, @Greater)
{ x > y — критерий сравнения для невозрастающей последовательности }
END.
Вариант № 1
[править]// narayana.php
function nextPermutation(array $sequence, int $count) {
$out = $sequence;
// Этап № 1
$k = $count - 2;
while ($k >= 0 && $out[$k] >= $out[$k + 1]) {
--$k;
}
if (-1 == $k) {
return false; // Перебор закончен
}
// Этап № 2
$t = $count - 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(($count + $k) / 2); ++$i) {
$t = $count + $k - $i;
$tmp = $out[$i];
$out[$i] = $out[$t];
$out[$t] = $tmp;
}
return $out;
}
Вариант № 2
[править]Вариант с выводом справа налево:
// narayana.php
$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/>’;
}
# narayana.py
"""Поиск очередной перестановки"""
def next_permutation(sequence, compare) -> bool:
count = len(sequence)
i = count
# Этап № 1
while True:
if i < 2:
return False # Перебор закончен
i -= 1
if compare(sequence[i - 1], sequence[i]):
break
# Этап № 2
j = count
while j > i and not compare(sequence[i - 1], sequence[j - 1]):
j -= 1
sequence[i - 1], sequence[j - 1] = sequence[j - 1], sequence[i - 1]
# Этап № 3
j = count
while i < j - 1:
j -= 1
sequence[i], sequence[j] = sequence[j], sequence[i]
i += 1
return True
Пример использования на Python 3.x (в Python 2.x надо убрать скобки в операторах print
):
# narayana_test.py
import narayana
"""Возвращает True, если value_0 меньше value_1, иначе — False"""
def less(value_0, value_1) -> bool:
return value_0 < value_1
"""Возвращает True, если value_0 больше value_1, иначе — False"""
def greater(value_0, value_1) -> bool:
return value_0 > value_1
# Основная программа
count = int(input())
sequence = list(range(1, count + 1)) # Заполнение последовательности значениями 1, 2, 3…
print("Неубывающая последовательность и её перестановки:")
permutation_found = True
while permutation_found:
print(sequence)
permutation_found = narayana.next_permutation(sequence, less)
# x < y — критерий сравнения для неубывающей последовательности
print("Невозрастающая последовательность и её перестановки:")
permutation_found = True
while permutation_found:
print(sequence)
permutation_found = narayana.next_permutation(sequence, greater)
# x > y — критерий сравнения для невозрастающей последовательности
// narayana.rs
// Поиск очередной перестановки
fn next_permutation <T: Copy + PartialOrd> (sequence: &mut[T], compare: fn (T, T) -> bool) -> bool {
let count = sequence.len();
let mut i = count;
// Этап № 1
while {
if i < 2 {
return false; // Перебор закончен
}
i -= 1;
!compare(sequence[i - 1], sequence[i])
} { } // Пустое тело цикла (имитация цикла с постусловием)
// Этап № 2
let mut j = count;
while j > i && !compare(sequence[i - 1], sequence[j - 1]) {
j -= 1;
}
sequence.swap(i - 1, j - 1);
// Этап № 3
j = count;
while i < j - 1 {
j -= 1;
sequence.swap(i, j);
i += 1;
}
true
}
Пример использования:
// narayana_test.rs
use narayana;
// Возвращает true, если value_0 меньше value_1, иначе — false
fn less <T: PartialOrd> (value_0: T, value_1: T) -> bool {
value_0 < value_1
}
// Возвращает true, если value_0 больше value_1, иначе — false
fn greater <T: PartialOrd> (value_0: T, value_1: T) -> bool {
value_0 > value_1
}
// Инициализация последовательности
fn init_sequence (sequence: &mut [i32]) {
// Заполнение последовательности значениями 1, 2, 3…
let mut i = sequence.len();
let mut value = i as i32;
while i > 0 {
i -= 1;
sequence[i] = value;
value -= 1;
}
}
// Функция для ввода данных
fn read_var <Type: std::str::FromStr> (var: &mut Type) -> bool {
let mut input_text = String::new();
std::io::stdin()
.read_line(&mut input_text)
.expect("Не удалось прочитать из стандартного ввода.");
match input_text.trim().parse::<Type>() {
Ok(value) => { *var = value; true },
Err(..) => { false }
}
}
// Основная программа
fn main () {
let mut count = 0usize;
read_var(&mut count);
let mut sequence = vec![0i32; count];
init_sequence(&mut sequence); // Формирование исходной последовательности
println!("Неубывающая последовательность и её перестановки:");
while {
println!("{:?}", sequence);
narayana::next_permutation(&mut sequence, less::<i32>)
// x < y — критерий сравнения для неубывающей последовательности
} { }
println!("Невозрастающая последовательность и её перестановки:");
while {
println!("{:?}", sequence);
narayana::next_permutation(&mut sequence, greater::<i32>)
// x > y — критерий сравнения для невозрастающей последовательности
} { }
}
// narayana.ts
//создаем начальную структуру (при n=5 => "01234")
const getStartPatternString = (n: number): string => {
if (n < 1) return "";
let startPatternString = '';
let i = 0;
while (i < n) {
startPatternString += i;
i++;
}
return startPatternString;
}
//Выводит в массиве все варианты возможных перестановок для начальной структуры "0123...n"
function narayana(n: number): string[] {
let b = getStartPatternString(n);
let a = b.split("").reverse().join("");
let res = [a];
while (a != b) {
let i = 1;
while (a[i] > a[i - 1]) {
i++;
}
let j = 0;
while (a[j] < a[i]) {
j++;
}
let temp = a.split("");
let c = temp[j];
temp[j] = temp[i];
temp[i] = c;
a = temp.join("");
let x = a.slice(0, i).split("").reverse().join("");
let y = a.slice(i);
a = x + y;
res.push(a)
}
return res; // .sort() - можно добавить для упорядочивания вывода
}