Я проверял это на нескольких входах, и это работает.
Конечно, есть лучший способ сделать это, но я так и сделал:
#include <stdio.h>
int array1[] = {1, 2, 3}; //array can be {1,1,2,3} for example also
int array2[3];
int fixed[3];
void permWithRep(int array1[], int array2[],int fixed_index[], int size , int level){
if(level == size) return print_array(array2,size);
for(int k = 0; k< size; k++){
if(!is_present_in_fixed(fixed_index,level,k)){
fixed_index[level] = k;
array2[level] = array1[k];
permWithRep(array1,array2,fixed_index,size,level+1);
}
}
}
void print_array(int array[], int size){
for(int k = 0; k < size; k++)printf("%d ",array[k]);
printf("\n");
}
int is_present_in_fixed(int array[], int size, int element ){
for(int k =0; k<size;k++)
if(element == array[k]) return 1;
return 0;
}
int main()
{
int len = sizeof(array1)/sizeof(int);
permWithRep (array1, array2, fixed, len, 0);
return 0;
}
Что я сделал:
- Добавить массив (
fixed_index[]
) которые отслеживают уже посещенные индексы для одной перестановки. - В цикле проверьте, принадлежит ли индекс текущего элемента к индексу, который уже посещен вэта перестановка (
is_present_in_fixed(fixed_index,level,k)
). - Если это так, он просто пропускает этот элемент (он не вводит оператор
if
). - В противном случае добавляет этот элемент к посещенному для этой перестановки и продолжаем с рекурсивным вызовом.
- Когда весь массив был итерирован (
level == size
), просто выведите результаты, содержащиеся в array2
.