① 以r1为开头,对剩下的元素进行全排列,并且把r1放到first_item[]数组当中。
② 先判断first_item[]数组中是否有元素等于r2,如果有则跳到③,否则把r2和r1进行交换,对剩下的元素进行全排列,然后再交换回来,并且把r2放进first_item[]数组里。
③ 接下来依次对r3, r4, …, rn做类似于②的操作。
#include <stdio.h>
#include <stdlib.h>
int n, count = 0;
void print_array(char item[], int n) //输出一种排列
{
FILE *w = fopen("output.txt", "a");
int i = 0;
for (i = 0; i < n; i++)
{
fprintf(w, "%c", item[i]);
}
fputc('\n', w);
fclose(w);
}
_Bool is_in_first_item(char item[], char x, int n) //判断x是否在item[]中,n为item[]的最大下标
{
if (n == -1)
return 0;
int i;
for (i = 0; i <= n; i++)
{
if (item[i] == x)
return 1;
}
return 0;
}
void swap(char item[], int index1, int index2) //交换item[index1]和item[index2]
{
char tmp;
tmp = item[index1];
item[index1] = item[index2];
item[index2] = tmp;
}
void full_permutation(char item[], int low, int high) //对item[]中下标为从low到high的元素进行全排列
{
if (low == high)
{
print_array(item, n);
count++;
}
else
{
int i, j = 0;
char *first_item = (char*)calloc(high - low + 1, sizeof(char)); //用来存放已进行过排列的首元素
for (i = low; i <= high; i++)
{
if (!is_in_first_item(first_item, item[i], j - 1)) //用于去重
{
swap(item, low, i);
full_permutation(item, low + 1, high);
swap(item, low, i);
first_item[j] = item[i];
j++;
}
}
free(first_item);
}
}
int main(void)
{
char filename_r[] = "./test/perm10.in";
FILE *r = fopen(filename_r, "r");
char item[50];
fscanf(r, "%d%s", &n, item);
fclose(r);
full_permutation(item, 0, n - 1);
FILE *w = fopen("output.txt", "a");
fprintf(w, "%d\n", count);
fclose(w);
return 0;
}
运行结果: