2 / 2 / 0
Регистрация: 22.11.2013
Сообщений: 101
1

Для заданного n получить все возможные перестановки чисел 1,2,...n

09.11.2014, 20:31. Показов 11566. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите, как решается эта задача.
Для заданного n получить все возможные перестановки чисел 1,2..n.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.11.2014, 20:31
Ответы с готовыми решениями:

Рекурсия: Создайте процедуру, печатающую все возможные перестановки для целых чисел от 1 до N.
Создайте процедуру, печатающую все возможные перестановки для целых чисел от 1 до N. помогите...

Все возможные перестановки элементов заданного массива
Помогите вывести на консоль все возможные перестановки элементов заданного массива void...

Все возможные перестановки листа чисел
Помогите, пожалуйста. Нужен метод, который возвращает все возможные перестановки чисел. Чтобы вот...

Дано n различных чисел, напечатать все возможные перестановки этих чисел
здраствуйте! пожалуйста помогите решить одну задачу (Дано n различных чисел, напечатать все...

9
4816 / 2276 / 287
Регистрация: 01.03.2013
Сообщений: 5,943
Записей в блоге: 27
09.11.2014, 20:40 2
Решается просто - n! Приходится к такому решению по-разному, можно так - для 1,2 у нас 2 перестановки, при добавлении к любой последовательности очередного элемента количество перестановок умножается на порядковый номер этого элемента - то есть, сколько он может занимать положений внутри исходного списка, умноженное на количество перестановок списка.
1
Вездепух
Эксперт CЭксперт С++
11182 / 6125 / 1677
Регистрация: 18.10.2014
Сообщений: 15,424
09.11.2014, 22:27 3
Лучший ответ Сообщение было отмечено Линда95 как решение

Решение

Цитата Сообщение от Линда95 Посмотреть сообщение
Для заданного n получить все возможные перестановки чисел 1,2..n.
Эта задача является классикой программирования. Если на элементах последовательности задать строгий порядок (который естественен для набора различных целых чисел), то существует простой алгоритм, который генерирует все перестановки, одну за другой, в лексикографическом порядке.

http://en.wikipedia.org/wiki/P... phic_order

1. Начинаем с A = { 1, 2, ..., n }
2. Находим максимальное i, такое что A[i] < A[i + 1]
3. Находим максимальное j, j > i, такое что A[i] < A[j]
4. Обмениваем местами A[i] и A[j]
5. Зеркально перворачиваем подмассив в диапазоне [i+1, n]
6. Переходим на шаг 2

Алгоритм завершается, если на шаге 2 мы не можем найти такого i, т.е. когда все элементы расположились в убывающем порядке.

Добавлено через 46 минут
Вот, например, прямая реализация этого алгоритма в моем фирменном стиле

Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
 
unsigned find_i(const unsigned a[], unsigned n)
{
  unsigned i;
 
  assert(n > 0);
 
  for (i = n - 2; i != -1; --i)
    if (a[i] < a[i + 1])
      break;
 
  return i;
}
 
unsigned find_j(const unsigned a[], unsigned n, unsigned i)
{
  unsigned j;
 
  assert(n > 0 && i < n - 1);
 
  for (j = n - 1; j != i; --j)
    if (a[j] > a[i])
      break;
 
  return j;
}
 
void swap(unsigned a[], unsigned i, unsigned j)
{
  unsigned tmp = a[i];
  a[i] = a[j];
  a[j] = tmp;
}
 
void reverse(unsigned a[], unsigned n)
{
  assert(n > 0);
 
  for (unsigned i = 0, j = n - 1; i < j; ++i, --j)
    swap(a, i, j);
}
 
bool next_permutation(unsigned a[], unsigned n)
{
  assert(n > 0);
 
  unsigned i = find_i(a, n);
  if (i == -1)
    return false;
 
  assert(n > 1);
 
  unsigned j = find_j(a, n, i);
  swap(a, i, j);
  reverse(a + i + 1, n - i - 1);
 
  return true;
}
 
void print(unsigned a[], unsigned n)
{
  for (unsigned i = 0; i < n; ++i)
    printf("%u ", a[i]);
 
  printf("\n");
}
 
#define N 6u
 
int main()
{
  unsigned a[N];
 
  for (unsigned i = 0; i < N; ++i)
    a[i] = i + 1;
 
  do
    print(a, N);
  while (next_permutation(a, N));
}


Добавлено через 1 минуту
Цитата Сообщение от _Ivana Посмотреть сообщение
Решается просто - n!
В задаче вроде требуется получить сами перестановки, а не посчитать их количество...
2
4816 / 2276 / 287
Регистрация: 01.03.2013
Сообщений: 5,943
Записей в блоге: 27
09.11.2014, 23:09 4
Лучший ответ Сообщение было отмечено Линда95 как решение

Решение

Действительно, это более вероятный вариант трактовки задания. Тогда я "в моем фирменном стиле" предложил бы рекурсия в 2 строчки.

Добавлено через 34 минуты
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int n, m[100], c;
void perms(int k)
{
    if (k==n) {printf("%d:\t",++c); for (int i=0; i<n; i++) printf("%d", m[i]); printf("\n");}
    else for (int i=1; i<=n; i++) {
            int f=0; for (int j=0; j<k; j++) if (m[j]==i) f=1;
            if (f) continue;
            m[k] = i; perms(k+1);
        }
}
int _tmain(int argc, _TCHAR* argv[]) 
{
    printf("Input n (not so big :)) : "); scanf("%d", &n);
    c=0; perms(0);
    system("pause");
    return 0;
}
1
Вездепух
Эксперт CЭксперт С++
11182 / 6125 / 1677
Регистрация: 18.10.2014
Сообщений: 15,424
10.11.2014, 00:04 5
Цитата Сообщение от _Ivana Посмотреть сообщение
Тогда я "в моем фирменном стиле" предложил бы рекурсия в 2 строчки.
В данном случае рекурсия - не божественна. Божественен тот факт, что задача допускает эффективный способ разворота рекурсии в честный цикл, т.е. циклическое решение без сохранения "тяжелого" continuation state.
0
4816 / 2276 / 287
Регистрация: 01.03.2013
Сообщений: 5,943
Записей в блоге: 27
10.11.2014, 01:58 6
TheCalligrapher, если быть честным, хотя бы перед самим собой, то следует с вами согласиться. Почти всегда наличие альтернативного нерекурсивного алгоритма более божественно, чем рекурсия, и данный случай, похоже, не исключение. Хотя есть известная теорема насчет того, что любой рекурсивный алгоритм можно переписать через нерекурсивный, более того - есть явные схемы для этого: использование собственного стека вместо системного для сохранения контекста вызовов, но когда нерекурсивный алгоритм еще и хоть сколько-нибудь изящен - это только плюс. Но раз уж в этой теме вы реализовали божественный нерекурсивный алгоритм, то для симметрии и следования собственному стилю мне просто необходимо было продемонстрировать альтернативу из нескольких строчек рекурсии.
1
Модератор
Эксперт функциональных языков программированияЭксперт Python
35511 / 19987 / 4184
Регистрация: 12.02.2012
Сообщений: 33,152
Записей в блоге: 13
10.11.2014, 12:12 7
Можно предложить и другую идею (тоже рекурсивную).

1) Очевидно, что при n=2 результат = {(1,2),(2,1)}
2) При произвольном n ,берем набор перестановок от (n-1) и в каждую вставляем n на все места по очереди:

(1,2) -> (3,1,2) (1,3,2) (1,2,3)
(2,1) -> (3,2,1) (2,3,1) (2,1,3)

и т.д.

Конечно, лексикографический перебор эффективнее, но этот алгоритм, мне кажется, нагляднее.
1
4816 / 2276 / 287
Регистрация: 01.03.2013
Сообщений: 5,943
Записей в блоге: 27
10.11.2014, 14:24 8
Catstail, идей можно много разных предложить, но приходится учитывать возможности языка и стандартных библиотек. Ваше "берем - вставляем" отлично сработает на функциональных языках со списками, а на С с массивами вставлять элемент в массив ну очень неудобно. На другом языке я бы организовывал выборку из оставшегося списка элементов, а не снова полный перебор по всем n с пропуском тех, которые уже набраны, или быструю проверку на вхождение элемента в список одним оператором/функцией, а на С мне пришлось отдельный цикл городить. В общем, я хочу сказать, что ограничения языка могут сильно влиять на выбор конкретной реализации алгоритма.
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
35511 / 19987 / 4184
Регистрация: 12.02.2012
Сообщений: 33,152
Записей в блоге: 13
10.11.2014, 18:26 9
_Ivana, это да. Именно в Лиспе я так и делал. "Вставлять" в массив действительно неудобно, хотя и возможно.
0
2 / 2 / 0
Регистрация: 22.11.2013
Сообщений: 101
07.12.2014, 11:04  [ТС] 10
_Ivana, TheCalligrapher, Catstail, объясните,пожалуйста,алгоритм работы этой программы
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <stdio.h>
#include <conio.h>
 
#define N 4
 
void swap(int *a, int *b)
{
  int t;
 
  t=*a;
  *a=*b;
  *b=t;
}
 
void reverse(int * P,int m)
{
   int i=0, j=m;
   while(i<j)
   {
     swap(&P[i], &P[j]);
     ++i;
     --j;
   }
}
 
void antilex(int * P,int m)
{
  int i;
 
  if(m==0)
  {
    for(i=0; i<N; ++i)
      printf("%d ",P[i]);
    printf("\n");
  }
  else
  {
    for(i=0; i<=m; ++i)
    {
      antilex(P,m-1);
      if(i<m)
      {
        swap(&P[i], &P[m]);
        reverse(P,m-1);
      }
    }
  }
}
 
 int main()
{
  int i;
  int P[N];
 
  for(i=0; i<N; ++i)
    P[i] = i+1;
 
  antilex(P,N-1);
  getch();
}
0
07.12.2014, 11:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.12.2014, 11:04
Помогаю со студенческими работами здесь

Дано n натуральных чисел. Определить все возможные перестановки этих чисел
дано n натуральных чисел. определить все возможные перестановки этих чисел C#

Дано n различных чисел, напечатать все возможные перестановки этих чисел
Помогите пожалуйста решить задачу через рекурсию: Дано n различных чисел, напечатать все возможные...

Вывести все возможные варианты перестановки чисел из n элементов по m
Задан массив чисел из n элементов. Вывести все возможные варианты перестановки из n элементов по m.

Ввести число. Используя рекурсивную функцию, получить все возможные перестановки цифр этого числа
Помогите пожалоста..........Заранеє спасибо

составить программу, выводящую на экран все возможные перестановки чисел, входящих в состав одномерного числового массива
составить программу, выводящую на экран все возможные перестановки чисел, входящих в состав...

Написать программу, в которой для n элементов строки на экран выведутся все возможные перестановки
Нужно написать программу, в которой для n элементов строки на экран выведутся все возможные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru