Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.05.2011, 16:14   #1
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
Восклицание Сочетания и алгоритм их получения

Устал гуглить, а заказик сдавать через несколько часов. Всё то работает, но одна процедура сделана по шумок, типа пока пусть будет так... вот хочу всё сделать на совесть.

Есть массив от "0" до "n-1" с элементами равными (1,2,3,...,n). Нужно создать функцию: закидываем этот массив, количество его элементов и на выходе получаем наш же массив, но первые m элементов(где m<n) составляют новое сочетание(т.е. функция переставляет местами элементы массива).
И вот наша задача вставить такую функцию в цикл от "1" до "возможного количества сочетаний для данного массива", приписать в этом же цикле под нашей функцией вывод на экран массива(первых m членов достаточно). В итоге получить следующее:

Для 4 позиций(m=4) и шести элементов(n=6) массив выглядит так: 1,2,3,4,5,6. Должны получить:
Код:
1234
1235
1236
1245
1246
1256
1345
1346
1356
1456
2345
2346
2356
2456
3456
Помогите с алгоритмом. Заранее благодарен.
Ksardas13 вне форума Ответить с цитированием
Старый 22.05.2011, 16:44   #2
Vago
Форумчанин
 
Регистрация: 15.01.2010
Сообщений: 948
По умолчанию

Что-то сегодня народ здесь на комбинаторику потянуло!..
...
Цитата:
Сообщение от Ksardas13 Посмотреть сообщение
...наша задача вставить такую функцию в цикл от "1" до "возможного количества сочетаний для данного массива", приписать в этом же цикле под нашей функцией вывод на экран массива(первых m членов достаточно)...
Как по мне - лучше вставлять не в цикл, а в саму себя.

Цитата:
Сообщение от Ksardas13
Помогите с алгоритмом. Заранее благодарен.
Код:
#!/usr/bin/python
# -*- coding: cp1251 -*-

a = ['1', '2', '3', '4']
m = 2
z = range( m )


def Cnm( a, j ):
    if j <= m:
        for i in range(0,len(a) ):
            z[j-1] = a[i]
            _a = []
            for l in range(i+1,len(a) ):
                _a.append( a[l] )
            Cnm( _a, j+1 )
    else:
        print z
        return

Cnm( a, 1 )

#
На Цэ сами переложите, надеюсь?..
Vago вне форума Ответить с цитированием
Старый 22.05.2011, 16:51   #3
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Ksardas13

Помогите с алгоритмом. Заранее благодарен.

алгоритм называется lulz
здесь демонстрация его применения
Rififi вне форума Ответить с цитированием
Старый 22.05.2011, 17:02   #4
Spawn™Production®
Форумчанин
 
Аватар для Spawn™Production®
 
Регистрация: 06.05.2011
Сообщений: 287
По умолчанию

А смысл при данных условиях делать перестановку элементов массива? Решается-то всё несколькими циклами...
Spawn™Production® вне форума Ответить с цитированием
Старый 22.05.2011, 17:40   #5
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
По умолчанию

Спасибо большое, буду копаться.))

Цитата:
А смысл при данных условиях делать перестановку элементов массива? Решается-то всё несколькими циклами...
Эм, наверное я плохо понял ваше предложение, но... Пусть N=100, а M=50. Во сколько тогда превратится "несколько циклов"?))
Пример с n=6 это всего лишь пример.)

Цитата:
Как по мне - лучше вставлять не в цикл, а в саму себя.
Желание заказчика порой бывают извращённы.))
Пытаюсь удовлетворить.)

Последний раз редактировалось Ksardas13; 22.05.2011 в 18:46.
Ksardas13 вне форума Ответить с цитированием
Старый 22.05.2011, 18:24   #6
Spawn™Production®
Форумчанин
 
Аватар для Spawn™Production®
 
Регистрация: 06.05.2011
Сообщений: 287
По умолчанию

Цитата:
Во сколько тогда превратится "несколько циклов"?))
Столько же, сколько и при N=100000;
Spawn™Production® вне форума Ответить с цитированием
Старый 22.05.2011, 19:06   #7
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
По умолчанию

Ага, начинаю понимать что Вы имеет ввиду! Наверное. Вот вчера ночью пытался эти циклы вывести... Не подскажете какой они имеют вид?
Первое на чём остановился - это цикл тупо сдвигающий массив влево(а первый элемент идёт на место последнего) до тех пор, пока он не вернётся в исходное состояние. Так получаем 6 комбинаций из 15-ти приведённых в примере. Как получить остальные?
Ksardas13 вне форума Ответить с цитированием
Старый 22.05.2011, 19:58   #8
Vago
Форумчанин
 
Регистрация: 15.01.2010
Сообщений: 948
По умолчанию

Цитата:
Сообщение от Ksardas13 Посмотреть сообщение
Желание заказчика порой бывают извращённы.))
Пытаюсь удовлетворить.)
В смысле? Заказчик поставил жёсткое условие - не использовать рекурсию?
Vago вне форума Ответить с цитированием
Старый 22.05.2011, 20:24   #9
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
По умолчанию

Заказчик студент. Задание из некой криво написанной методы для преподши, которая С++ читает впервые(я сам в шоке)).
Вот там строго прописана процедура, возвращающая перестановки массива(номеров массива), которая крутится в почти бесконечном цикле, пока не выполнится определённое условие(ищем геометрические фигуры, среди множества точек).
Но приведённая процедура в методе не даёт всех сочетаний... вот мучаюсь как бы её исправить -_-

Если б не это ограничение, мозг бы болел меньше.
Ksardas13 вне форума Ответить с цитированием
Старый 22.05.2011, 20:34   #10
Vago
Форумчанин
 
Регистрация: 15.01.2010
Сообщений: 948
По умолчанию

Цитата:
Сообщение от Ksardas13 Посмотреть сообщение
... которая С++ читает впервые(я сам в шоке)).
Всё в этой жизни когда-нибудь приходится делать впервые...
...
Ну, держите ещё с индексами, без выдёргивания подмассива.
Код:
#include <iostream>
using namespace std ;

int* a ;
const int  n = 5 ,
           m = 3 ;


void PrintCnm( int* a ) {

   for ( int i = 0; i < m; i++ )
      cout << a[i] << ' ' ;
   cout << endl ;

}


void Cnm( int k ) {

   if ( k >= 0 ) {
// BAD! BAD!! BAD!!!      if ( a[k] < n+k-1 ) {
      if ( a[k] < n+k-m+1 ) {
         ++a[k] ;
         for ( int i = k+1; i < m; i++ ) 
            a[i] = a[i-1]+1 ;
         PrintCnm( a ) ;
         Cnm( m-1 ) ;
      } else
         Cnm( k-1 ) ;
   } else
      return ;

}


int main() {

   a = new int[m] ;

   for ( int i = 0; i < m; i++ )
      a[i] = i+1 ;
   PrintCnm( a ) ;

   Cnm( m-1 ) ;

   delete []a ;      

   return 0 ;

}
Added 19:47 CET:
Извините, с верхним пределом цикла в одном месте ошибся.

Последний раз редактировалось Vago; 22.05.2011 в 21:46.
Vago вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C# всевозможные сочетания xil Общие вопросы .NET 8 04.01.2011 17:53
Двубуквенные сочетания 0479 Общие вопросы по Java, Java SE, Kotlin 0 07.11.2010 19:56
Клавиатурные сочетания kzld Microsoft Office Excel 2 13.09.2010 14:51
Алгоритм получения диапазона IP zAlexandrz Общие вопросы Delphi 4 26.02.2010 22:43
Сочетания. Пaвeл Помощь студентам 2 12.03.2009 07:57