Помогите, пожалуйста, решить задачку...

 

Меня интересует не конкретный код, а алгоритм решения.

Задача такова:

есть несколько значений, скажем: a,b,c,d

Нужно сгенерировать все возможные комбинации из них, отбросив лишние (повторяющиеся, или имеющие в ряду повторяющиеся значения).

Количество значений может менятся от случая к случаю, но может подставлятся перед запуском скрипта (если это нужно).

Значения могут иддти не подряд, т.е.: a,c,e,h,y

В итоге должно получиться что-то вроде этого:

для a,b,c,d

a

ab

ac

ad

abc

acd

b

bc

bd

bcd

c

cd

d

 

для начала надо посчитать количество неповторяющихся (уникальных)значений, потом разложить их в ряд ( по возрастанию как у вас показанно),потом начиная например с наименьшего прописываем все комбинации с ним в отдельные ряды, когда комбинации заканчиваются удаляем первое значение из исходного ряда и повторяем весь процесс, и так пока переменные не закончатся. в конце сортируем получившиеся ряды ( по возрастанию) как у вас показанно.

 
xrust писал(а) >>

для начала надо посчитать количество неповторяющихся (уникальных)значений, потом разложить их в ряд ( по возрастанию как у вас показанно),потом начиная например с наименьшего прописываем все комбинации с ним в отдельные ряды, когда комбинации заканчиваются удаляем первое значение из исходного ряда и повторяем весь процесс, и так пока переменные не закончатся. в конце сортируем получившиеся ряды ( по возрастанию) как у вас показанно.

я об этом думал - сам итог на это наводит!

но есть загвоздка - значений может быть и 5 и 100, как тогда сгенерировать из a,b,c,d,e скажем a+c+e?

или я недопонял?

 
читайте внимательно когда комбинации заканчиваются удаляем первое значение из исходного ряда
 
xrust писал(а) >>
читайте внимательно когда комбинации заканчиваются удаляем первое значение из исходного ряда

до этого.

"потом начиная например с наименьшего прописываем все комбинации с ним в отдельные ряды", т.е. например для "a" одна из комбинаций будет

a+c+e, когда все для "a" перебрал, я его исключаю.

но я не могу получить a+c+e! ну мозга мне нехватает...

как выкинуть из ряда в сотни значений разное в каждом цикле количество значений из разных мест!?

 

Отличная задачка! Но проще написать, чем объяснить.

#property copyright "Integer"
#property link      "for-good-letters@yandex.ru"

int start(){

   string Elements[]={"a","b","c","d"};
   string Variants[]; // Массив для всех вариантов перестановок элементов из массива Elements
   
   ArrayResize(Variants,0);  
   
      for(int i=1;i<=4;i++){
         // добавляем в массив Variants варианты из i элементов
         fAddVariantsToList(
                                 Elements,   // массив с элементами
                                 i,          // количество элементов в варианте
                                 1,      // повоторять или нет элементы в варианте
                                 Variants    // возвращаемый массив с вариантами
                           );
      }
     
   // смотрим, что получилось
     
   Alert("============== Начало ================");
      for(i=0;i<ArraySize(Variants);i++){
         Alert((i+1)+ " - " + Variants[i]);
      }
   Alert("============== Конец (всего "+ArraySize(Variants)+") =================");
      
   return(0);
}

void fAddVariantsToList(string aElements[],int aCount,bool aRepeat,string & aList[]){

   // функция добавляет в массив aList варианты из aCount элементов. Элементы в массиве aElements
   // aRepeat - true - допускается повторение элементов в одном варианте, false - не допускается

   int tIndexes[];
   ArrayResize(tIndexes,ArraySize(aElements));
   fRecurrence(aElements,0,tIndexes,aCount,aRepeat,aList);
}

void fRecurrence(string aElements[],int aCallIndex,int & aIndexes[],int aCount,bool aRepeat,string & aList[]){
   aCount=MathMin(aCount,ArraySize(aIndexes));
      for(int i=0;i<ArraySize(aIndexes);i++){
         aIndexes[aCallIndex]=i;
            if(aCallIndex==aCount-1){
              bool tAdd=true;
                  if(!aRepeat){
                     for(int j=0;j<aCount;j++){
                        for(int k=0;k<aCount;k++){
                           if(j!=k){
                              if(aIndexes[j]==aIndexes[k]){
                                 tAdd=false;
                              }
                           }
                        }
                     }     
                  }
                  if(tAdd){
                     string str="";
                        for(j=0;j<aCount;j++){
                           str=str+aElements[aIndexes[j]];
                        }            
                     ArrayResize(aList,ArraySize(aList)+1);
                     aList[ArraySize(aList)-1]=str;  
                  }
            }
            else{
               fRecurrence(aElements,aCallIndex+1,aIndexes,aCount,aRepeat,aList);
            }
      } 
}
Файлы:
 
Integer писал(а) >>

Отличная задачка! Но проще написать, чем объяснить.

ДА! спасибо огромное!

 
Integer >>:

Отличная задачка! Но проще написать, чем объяснить.

Силен, бродяга!

Причина обращения: