Объясню сразу на примере, так понятней.
Допустим есть числовой ряд 1234. Надо организовать все возможные перестановки. Насколько помню из курса комбинаторики, это n!, где n - кол-во элементов в ряду. т е должны получится:
1234 2134 3124 4123
1243 2143 3142 4132
1324 2314 3214 4213
1342 2341 3241 4231
1423 2413 3412 4312
1432 2431 3421 4321
Число элементов числового рядо переменно.
Все мои попытки оказались неудачными, погуглил - все время предлагают обойти полный перебор =)
Другие языки программирования и технологии
Алгоритм перестановок элементов числового ряда
Это Java, думаю в целом понять можно.
Это манипуляции с массивом, числа в принципе могут быть непоследовательными и одинаковыми (немного надо будет подправить, например, первый комментарий заменить на if( i==-1 ) break; )
Приблизительно тоже можно увидеть в книге
Витольд Липский, Комбинаторика для программистов. - М.: Мир, 1988.
Числа тут выдаются по 10, а не по n, это легко, я думаю, исправить.
[code] - это тэг не рабтает, увы.
public static String perm1(final int n ){
.//лексикографический порядок.
.if( n < 0 ) return "Некорректные параметры. ";
.if( n == 0 ) return "Нечего переставлять";
.if( n == 1 ) return "1";
.int p = CIMath.iFactorial(n); //доморощенный факториал
.if( n > 6 ) return "Число перестановок слишком велико для вывода. ";
.StringBuffer sb = new StringBuffer( p*(n+2) );
.int[] ap = new int[ n ];
.for(int i=0; i < n; i++){
..ap[ i ]=i+1;
..sb.append(http://Integer.toString(i+1));
.}
.sb.append(" ");
.final int nn = n-1;
.for(int s=1; s < p; s++){
..int i = nn-1;
..for(; i>=0; i--) if( ap[ i ] < ap[ i+1 ] ) break;
..//if( i==-1 ) return "внутренняя ошибка 1";
..int k = ap[ i ];
..int j = nn;
..for(; j >=i; j--) if( k < ap[ j ] ) break;
..//if( j==i-1 ) return "внутренняя ошибка 2";
..ap[ i ]=ap[ j ];
..ap[ j ]=k;
..for( j=1; j < = (nn-i)/2; j++ ){
...k=ap[ i+j ];
...ap[ i+j ]=ap[ n-j ];
...ap[ n-j ]=k;
..}
..for( i=0; i < n; i++ ) sb.append( http://Integer.toString(ap[ i ]) );
..if((s+1) % 10==0) sb.append('\n'); else sb.append(" ");
.}
.return http://sb.toString();
}
[/code]
У меня есть перестановки и выборки n элементов из множества m элементов.
код может быть искажен местным форматированием, от http://Integer.toString() избавится не удалось.
Это манипуляции с массивом, числа в принципе могут быть непоследовательными и одинаковыми (немного надо будет подправить, например, первый комментарий заменить на if( i==-1 ) break; )
Приблизительно тоже можно увидеть в книге
Витольд Липский, Комбинаторика для программистов. - М.: Мир, 1988.
Числа тут выдаются по 10, а не по n, это легко, я думаю, исправить.
[code] - это тэг не рабтает, увы.
public static String perm1(final int n ){
.//лексикографический порядок.
.if( n < 0 ) return "Некорректные параметры. ";
.if( n == 0 ) return "Нечего переставлять";
.if( n == 1 ) return "1";
.int p = CIMath.iFactorial(n); //доморощенный факториал
.if( n > 6 ) return "Число перестановок слишком велико для вывода. ";
.StringBuffer sb = new StringBuffer( p*(n+2) );
.int[] ap = new int[ n ];
.for(int i=0; i < n; i++){
..ap[ i ]=i+1;
..sb.append(http://Integer.toString(i+1));
.}
.sb.append(" ");
.final int nn = n-1;
.for(int s=1; s < p; s++){
..int i = nn-1;
..for(; i>=0; i--) if( ap[ i ] < ap[ i+1 ] ) break;
..//if( i==-1 ) return "внутренняя ошибка 1";
..int k = ap[ i ];
..int j = nn;
..for(; j >=i; j--) if( k < ap[ j ] ) break;
..//if( j==i-1 ) return "внутренняя ошибка 2";
..ap[ i ]=ap[ j ];
..ap[ j ]=k;
..for( j=1; j < = (nn-i)/2; j++ ){
...k=ap[ i+j ];
...ap[ i+j ]=ap[ n-j ];
...ap[ n-j ]=k;
..}
..for( i=0; i < n; i++ ) sb.append( http://Integer.toString(ap[ i ]) );
..if((s+1) % 10==0) sb.append('\n'); else sb.append(" ");
.}
.return http://sb.toString();
}
[/code]
У меня есть перестановки и выборки n элементов из множества m элементов.
код может быть искажен местным форматированием, от http://Integer.toString() избавится не удалось.
дык.. .
n!
это для случая когда у тебя ряд из n разных элементов.. .
если же элементы повторяются, то и формула другая.. .
читай комбинаторику ещё)))
n!
это для случая когда у тебя ряд из n разных элементов.. .
если же элементы повторяются, то и формула другая.. .
читай комбинаторику ещё)))
Александр Скутин
Не уточнил своевременно формулировку "перестановки без повторений". В каждой из приведенных мною комбинациях нет ни одного числа, которое бы повторялось. Так что читать еще раз комбинаторику не придется, но боюсь, что придется читать что-то другое)
Потому и предлагают, что по другому не получится!!!
Александр Скутин
Вы, конечно же, заработали свои "+2 балла". Но вопрос по поводу поиска алгоритма. Полный перебор - это всего лишь способ выполнить что-либо и это не касаемо моего вопроса. Его не используют не потому что "не получится!!!", а потому что он очень требователен к ресурсам ЭВМ. Потому смею обосрать ваше гениальное замечание
Сальвадор Дали
Вы конечно можете обсирать все, что угодно. Другой вопрос, зачем Вам это нужно, т.е если это нужно, чтобы организовать поиск, то существует множество алгоритмов по этому поводу, а если это написано не понятно для чего....то тут уж и нет смысла решать эту проблему.
Похожие вопросы
- Разработка в среде TURBO PASCAL программы перестановки элементов массива.
- Разработка в среде TURBO PASCA программы перестановки элементов массива.
- Напишите программу для расчета среднего арифметического всех элементов числового массива рекурсией
- Найти сумму числового ряда с заданной точность епсилон (вводится пользователем): S = 1+1/22+ 1/32+ 1/42+ 1/52+ …
- алгоритм... по нахождению общих элементов двух массивов
- программирование pascal (паскаль) алгоритм с перестановкой цифр в числе
- Отобразить элементы двумерного числового массива относительно горизонтальной оси.
- написать программу на с++ (windows) и алгоритм для решения последовательности n! перестановок на множестве {1,2...n}
- В упорядоченный по возрастанию числовой массив из 20 элементов вставить числа –4 и 7, не нарушая упорядоченности. pascal
- паскаль Ввести числовую матрицу {Aij}i=1,...n;j=1,...m. Найти произведение сумм элементов строк Помогите решить)