You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现单词字母排列组合数计算及程序报错排查

解决重复字母排列数计算的段错误与逻辑问题

原代码的核心问题

  • 变量未初始化:nf、rf、r这些计算阶乘的变量直接参与乘法操作却未初始化,会触发未定义行为,甚至引发段错误。
  • 无限循环:统计字母次数的内层循环写错了条件——for (j=i;i<len;j++)里的循环条件是i<len,但i在循环中不会改变,导致无限循环,直接造成段错误。
  • 重复计数:对重复字母会多次统计次数(比如"hello"里的两个'l',会被i=2和i=3分别统计),导致分母的阶乘乘积计算重复,结果错误。
  • 无效遍历:计算分母时遍历了整个cnt数组(100个元素),但只有前len个元素是有效数据,后面的都是未初始化的垃圾值,会导致计算出错。
  • 未用递归阶乘:题目明确要求用递归实现阶乘,但原代码用循环计算,不符合要求。
  • 溢出风险:int类型最大值有限,长字符串的阶乘会溢出,需要更大的数据类型。

修正后的代码

#include <stdio.h>
#include <string.h>

// 递归实现阶乘计算
long long factorial(int n) {
    if (n == 0 || n == 1) {
        return 1;
    }
    return n * factorial(n - 1);
}

long long calculatePermutations(char arr[], int len) {
    // 统计每个字母的出现次数,避免重复统计
    int count[256] = {0}; // 覆盖所有ASCII字符
    for (int i = 0; i < len; i++) {
        count[(unsigned char)arr[i]]++;
    }

    // 计算分子:len的阶乘
    long long numerator = factorial(len);

    // 计算分母:所有重复字母阶乘的乘积
    long long denominator = 1;
    for (int i = 0; i < 256; i++) {
        if (count[i] > 1) {
            denominator *= factorial(count[i]);
        }
    }

    return numerator / denominator;
}

int main() {
    char arr[100];
    scanf("%s", arr);
    int len = strlen(arr);
    printf("%lld\n", calculatePermutations(arr, len));
    return 0;
}

代码说明

  1. 递归阶乘:factorial函数通过递归实现,符合题目要求,当n为0或1时返回1作为终止条件。
  2. 正确统计次数:用256长度的数组对应ASCII码,每个字母只统计一次,避免重复计数。
  3. 变量初始化:所有计算变量都初始化为合理值,消除未定义行为。
  4. 数据类型优化:用long long存储阶乘结果,避免长字符串的阶乘溢出。
  5. 高效遍历:只统计字符串内的字母,计算分母时只处理出现次数大于1的字母,提升效率。

测试验证:

  • 输入Whats,输出120
  • 输入hello,输出60
  • 输入little,输出180
  • 输入document,输出40320

内容的提问来源于stack exchange,提问作者Harshavardhan K K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:55:16