Search code examples
cpermutationnon-recursive

generate all permutations with repetition....non-recursive in C


So I would like to know how to write a non-recursive function to print all permutations given an N and r where r^N gives you the total number of permutations.

Example: N = 3, r = 2, total permutations = 8

output:
000
001
010
011
100
101
110
111

This is what I tried but of course it only works for one case:

void perm_iter(int N, int nr_vals){

    int pos = N-1;
    int i,j,k;
    int P_array[N];
    for(i=0;i<N;i++){
        P_array[i] = 0;
    }
    int val_array[nr_vals];
    for(i=0;i<nr_vals;i++){
        val_array[i] = i;
    }

    do{
        for(i=0;i<N;i++){
            for(j=0;j<nr_vals;j++){
                P_array[pos-1] = val_array[j];
                for(k=0;k<nr_vals;k++){
                    P_array[pos] = val_array[k];
                    for(i=0;i<N;i++){
                        printf("%d",P_array[i]);
                    }
                    printf("\n");
                }
            }
            pos--;
        }
    }while(pos > 0);
}

Solution

  • This is an odometer function with variable radix, not really a permutation.

    #include <stdio.h>
    #include <stdlib.h>
    
    void show(int *a, int n)
    {
    int i;
        for(i = 0; i < n; i++)
            printf("%1d", a[i]);
        printf("\n");
    }
    
    void gen_all_numbers(int r, int n)
    {
    int i;
    int *a;
        if(r < 2 || n < 1)          /* parameter check */
            return;
        r -= 1;                     /* r = max digit value */
        a = malloc(n * sizeof(int));
        for(i = 0; i < n; i++)      /* start with all zeroes */
            a[i] = 0;
        show(a, n);
        while(1){
            i = n - 1;
            while(a[i] < r){        /* increment last digit */
                a[i]++;
                show(a,n);
            }
            /* find next digit to increment */
            while(i >= 0 && a[i] == r)
                i--;
            if(i < 0)break;         /* return if done */
            a[i]++;
            while(++i < n)          /* zero following digits */
                a[i] = 0;
            show(a,n);
        }
        free(a);
    }
    
    int main()
    {
        gen_all_numbers(2,4);
        return 0;
    }