所以我想知道如何编写一个非递归函数来打印给定N和r的所有排列,其中r^N
给出了排列的总数。
Example: N = 3, r = 2, total permutations = 8
output:
000
001
010
011
100
101
110
111
这是我尝试过的,但当然它只适用于一种情况:
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);
}
这是一个具有可变基数的里程计函数,而不是真正的置换。
#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;
}
这很有效。只要确保在编译时使用-lm
选项,否则就会出现有关pow
函数的错误。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void perm(double r,double N){
double num=pow(r,N);
int count=(int)num;
int n=0,b=0;
for (n=0;n<count;n++){
printf("%d: ",n);
for (b=2;b>=0;b--){ //go through bits 2 to 0.
if (n & (1<<b)){printf("1");}else{printf("0");}
}
printf("n");
}
}
int main(){
perm(2,3);
return 0;
}