Find all possible arrangements of a n numbers in an array

陌路散爱 提交于 2019-12-23 01:21:30

问题


I have an array which contains lets say [25,15,8,20] I want to find all possible arrangements of numbers that is possible.

expected output:

25 15 8 20
25 15 20 8
25 20 15 8
25 20 8 15
25 8 20 15
25 8 15 20
15 25 8 20
15 25 20 8
15 20 25 8
15 20 8 25
15 8 20 25
15 8 25 20
20 25 15 8
20 25 8 15
20 8 25 15
20 8 15 25
20 15 25 8
20 15 8 25
8 15 20 25
8 15 25 20
8 25 15 20
8 25 20 15
8 20 15 25
8 20 25 15


void print(int *num, int n)
{
 int i;
 for ( i = 0 ; i < n ; i++)
    printf("%d ", num[i]);
   printf("\n");
}
int main()
{
 int num[N];
 int *ptr;
 int temp;
 int i, n, j;
 printf("\nHow many number you want to enter: ");
    scanf("%d", &n);
 printf("\nEnter a list of numbers to see all combinations:\n");
 for (i = 0 ; i < n; i++)
    scanf("%d", &num[i]);
 for (j = 1; j <= n; j++) {
    for (i = 0; i < n-1; i++) {
        temp = num[i];
        num[i] = num[i+1];
        num[i+1] = temp;
        print(num, n);
 }
}
 return 0;
}

The above program is not giving all possible outputs. How do I get the internal swap and get the combinations


回答1:


  • The trick is, you must not permute only adjacent values, see that when 3 is fixed at the index=1, 4 is never aside it, so you must extend permutations to further values gradually.

    #include <stdio.h>  
    #include <string.h> 
    #include <malloc.h> 
    
    void print(int *num, int n) 
    {   
     int i; 
     for ( i = 0 ; i < n ; i++) 
        printf("%d ", num[i]);  
       printf("\n");    
    }   
    
    int*permute(int*i,int h)    
    {       
         int temp = *i; 
        *i = *(i+h);    
        *(i+h) = temp;  
    return i+1; 
    
    }   
    void recursive_permute(int*i,int *j,int n)  
    {   
        if((j-i)==n-1) {print(i,n);return;};
    
        int *tmparray=(int*)malloc(n*sizeof(int));
        memcpy(tmparray,i,n*sizeof(int));
        recursive_permute(tmparray,tmparray+(j-i+1),n);
    
        for (int h=1;h<n-(j-i);h++) recursive_permute(tmparray,permute(tmparray+(j-i),h),n);
    }   
    
    int main()  
    {   
     int num[100];  
     int *ptr;  
     int temp;  
     int i, n, j;   
     printf("\nHow many number you want to enter: ");   
        scanf("%d", &n);    
     printf("\nEnter a list of numbers to see all combinations:\n");    
     for (i = 0 ; i < n; i++)   
        scanf("%d", &num[i]);   
     printf("my recursive method ---------------------------\n");   
     recursive_permute(num,num,n);  
    
     printf("your method -----------------------------------\n");   
    
     for (j = 1; j <= n; j++) { 
        for (i = 0; i < n-1; i++) { 
            temp = num[i];  
            num[i] = num[i+1];  
            num[i+1] = temp;    
            print(num, n);  
     }  
    }   
     return 0;  
    }   
    

See it running here




回答2:


There are several aspect to finding all permutations and the number of permutations. Shown with comments below, to calculate the number of permutations for k size groups in a total on n elements, you find the factorial on n divided by the factorial for number of k size groups that can make up n elements. For the case of finding all permutations for all 4 elements in a four elements array, there are 24 possible permutations.

The permutations available are then found recursively. Look over the following and let me know if you have any questions:

#include <stdio.h>
#include <stdlib.h>

void swap (int *x, int *y);
unsigned long long nfact (size_t n);
unsigned long long pnk (size_t n, size_t k);
void permute (int *a, size_t i, size_t n);
void prnarray (int *a, size_t sz);

int main (void) {

    int array[] = { 25, 15, 8, 20 };
    size_t sz = sizeof array/sizeof *array;

    /* calculate the number of permutations */
    unsigned long long p = pnk (sz , sz);
    printf ("\n total permutations : %llu\n\n", p);

    /* permute the array of numbers */
    printf (" permutations:\n\n");
    permute (array, 0, sz);
    putchar ('\n');

    return 0;
}

/* Function to swap values at two pointers */
void swap (int *x, int *y)
{   int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

/* calculate n factorial */
unsigned long long nfact (size_t n)
{   if (n <= 0) return 1;
    unsigned long long s = n;

    while (--n) s *= n;

    return s;
}

/* calculate possible permutations */
unsigned long long pnk (size_t n, size_t k)
{   size_t d = (k < n ) ? n - k : 1;
    return nfact (n) / nfact (d);
}

/* permute integer array for elements 'i' through 'n' */
void permute (int *a, size_t i, size_t n)
{   size_t j;
    if (i == n)
        prnarray (a, n);
    else
        for (j = i; j < n; j++) {
            swap ((a+i), (a+j));
            permute (a, i+1, n);
            swap ((a+i), (a+j));  // backtrack
        }
}

void prnarray (int *a, size_t sz)
{   size_t i;
    for (i = 0; i < sz; i++) printf (" %2d", a[i]);
    putchar ('\n');
}

Use/Output

$ ./bin/permute4int

 total permutations : 24

 permutations:

 25 15  8 20
 25 15 20  8
 25  8 15 20
 25  8 20 15
 25 20  8 15
 25 20 15  8
 15 25  8 20
 15 25 20  8
 15  8 25 20
 15  8 20 25
 15 20  8 25
 15 20 25  8
  8 15 25 20
  8 15 20 25
  8 25 15 20
  8 25 20 15
  8 20 25 15
  8 20 15 25
 20 15  8 25
 20 15 25  8
 20  8 15 25
 20  8 25 15
 20 25  8 15
 20 25 15  8

Note: for strings, this approach works fine, but does not result in a lexical sorting of the possible permutations.



来源:https://stackoverflow.com/questions/32920005/find-all-possible-arrangements-of-a-n-numbers-in-an-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!