如何在C语言字符串全排列代码中正确统计生成的排列总数?
C语言全排列代码的排列数统计修正
原代码统计失效的核心原因
- 阶乘计算逻辑错误
原代码的阶乘循环终止条件设置为cont < len,仅计算了1到len-1的乘积,漏掉了乘len的步骤。比如输入"hi"时字符串长度为2,循环只会执行1次,算出的结果为1,和实际生成的2条排列不匹配。 - 纯阶乘统计的场景局限性
阶乘计算的是所有字符无重复时的全排列总数,如果输入字符串包含重复字符(比如"aab"),现有全排列逻辑会因交换相同字符生成大量重复排列,此时阶乘计算值会远大于实际输出的排列行数,统计结果失真。
适配需求的修正方案
方案1:直接统计实际打印的排列数(推荐,全场景适用)
这种方式统计的是程序实际输出的排列行数,完全匹配你要求的generated words: X输出格式,不受输入字符是否重复的影响。
调整步骤:
- 新增一个整型计数变量,初始值为0
- 因为
permute是递归函数,要修改计数变量需要通过指针传参,避免函数内修改的是局部变量副本 - 在
permute函数打印排列的分支里,每打印一个有效排列就将计数+1 - 所有排列生成完成后,直接输出计数结果
对应修正后的完整代码:
#include <string.h> #include <stdio.h> void swap (char *x, char *y) { char temp; temp = *x; *x = *y; *y = temp; } // permute函数新增计数指针参数 void permute(char *a, int i, int n, int *count) { int j; if (i == n) { printf("%s\n", a); (*count)++; // 每打印一个排列,计数+1 } else { for (j = i; j <= n; j++) { swap((a + i), (a + j)); permute(a, i + 1, n, count); swap((a + i), (a + j)); //backtrack } } } int main() { char str[21]; int len; int total_count = 0; // 排列计数初始化为0 printf("\nType a word: "); scanf("%s", str); len = strlen(str); // 调用递归函数时传入计数变量的地址 permute(str, 0, len - 1, &total_count); printf("\nNumber of letters: %d\n", len); // 按需求格式输出统计结果 printf("generated words: %d\n", total_count); return 0; }
输入"hi"运行时,程序会依次输出hi、ih,最后打印generated words: 2,完全符合预期。
方案2:修正阶乘计算逻辑(仅适用于无重复字符的输入场景)
如果确定输入的字符串所有字符均不重复,只需把原代码里错误的阶乘循环调整正确即可:
原错误循环逻辑:
int cont = 1; int fatorial = 1; // 错误:循环条件为cont < len,只乘到len-1 while (cont < len) { fatorial = fatorial * cont; cont++; }
修正后的阶乘计算逻辑,需要遍历从1到len的所有整数做乘积:
int fatorial = 1; for(int k = 1; k <= len; k++) { fatorial *= k; } printf("generated words: %d", fatorial);
注意:如果输入带重复字符,这个方法算出的结果会大于实际输出的排列数,因为原有全排列逻辑会生成重复条目。
内容的提问来源于stack exchange,提问作者Wagner
相关产品推荐
相关产品推荐

