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

C语言中如何将带重复的9选3全排列存储为二维数组?

修正带重复的10选3全排列存储代码及优化建议

我正在编写生成带重复的10选3全排列的程序,以下代码可正常打印排列结果:

#include <stdio.h>

int main() {

    for (int i = 0; i <= 9; i++) {
        for (int j = 0; j <= 9; j++) {
            for (int k = 0; k <= 9; k++) {
                printf("%d,%d,%d\n", i, j, k);
            }
        }
    }
    return 0;
}

但我希望将每个含3个元素的排列存储到一个二维数组中而非直接打印,尝试编写的以下代码无法正常运行:

int main() {

    int permutas[511][2];

    for (int i = 0; i <= 9; i++) {
        for (int j = 0; j <= 9; j++) {
            for (int k = 0; k <= 9; k++) {
                for (int q = 0; q < 512; q++) {
                    permutas[q][0] = i;
                    permutas[q][1] = j;
                    permutas[q][2] = k;
                }
            }
        }
    }
    return 0;
}

不知如何修正该代码,同时希望获取代码优化的相关建议。

错误分析

你的代码存在两个核心问题:

  1. 数组定义错误:
    • 带重复的10选3全排列总数是 10*10*10=1000 组,你定义的数组大小[511][2]完全不符合需求:行数仅512个(索引0到511),远小于实际需要的1000;列数为2,无法存储每组的3个元素,正确的数组定义应为[1000][3]。
  2. 循环逻辑错误:
    • 内层的q循环会在每一组i,j,k生成时覆盖数组的所有位置,最终所有元素都会被最后一组9,9,9覆盖。正确做法是用一个计数器变量,每生成一组排列就存入数组对应索引位置,再将计数器自增。

修正后的代码

#include <stdio.h>

#define TOTAL_PERMUTATIONS 1000  // 10^3=1000,总排列数
#define PERMUTATION_LENGTH 3     // 每组排列的元素个数

int main() {
    // 定义足够大小的二维数组存储所有排列
    int permutas[TOTAL_PERMUTATIONS][PERMUTATION_LENGTH];
    // 计数器,记录当前要存储的数组索引
    int count = 0;

    for (int i = 0; i <= 9; i++) {
        for (int j = 0; j <= 9; j++) {
            for (int k = 0; k <= 9; k++) {
                // 将当前排列存入数组对应位置
                permutas[count][0] = i;
                permutas[count][1] = j;
                permutas[count][2] = k;
                // 计数器自增,准备存储下一组
                count++;
            }
        }
    }

    // 可选:打印验证结果是否正确
    for (int idx = 0; idx < TOTAL_PERMUTATIONS; idx++) {
        printf("%d,%d,%d\n", permutas[idx][0], permutas[idx][1], permutas[idx][2]);
    }

    return 0;
}

代码优化建议

  • 用宏定义常量:像示例中那样把总排列数、每组元素长度定义为宏,后续修改数字范围或排列长度时,只需修改宏定义即可,避免多处修改出错。
  • 动态分配内存:如果排列总数很大(比如10选10),栈内存可能不足,此时可以用malloc动态分配内存,使用完毕后记得释放:
    int** permutas = malloc(TOTAL_PERMUTATIONS * sizeof(int*));
    for (int i = 0; i < TOTAL_PERMUTATIONS; i++) {
        permutas[i] = malloc(PERMUTATION_LENGTH * sizeof(int));
    }
    // 使用完成后释放内存
    for (int i = 0; i < TOTAL_PERMUTATIONS; i++) {
        free(permutas[i]);
    }
    free(permutas);
    
  • 封装成独立函数:将生成排列的逻辑封装成函数,方便复用和维护,比如:
    void generatePermutations(int** result, int numChoices, int length) {
        int count = 0;
        // 这里针对长度为3的情况,若要支持可变长度可改用递归
        for (int i = 0; i < numChoices; i++) {
            for (int j = 0; j < numChoices; j++) {
                for (int k = 0; k < numChoices; k++) {
                    result[count][0] = i;
                    result[count][1] = j;
                    result[count][2] = k;
                    count++;
                }
            }
        }
    }
    
  • 支持可变长度排列:如果需要生成任意长度的带重复全排列,建议用递归实现,避免嵌套循环的局限性(比如长度为n时需要n层循环)。

内容的提问来源于stack exchange,提问作者Matin Gomez-Pablos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:17:12