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

不使用动态内存,如何生成手机键盘字符组合的二维数组?

生成电话号码字母组合(无动态内存限制版)

首先修正并补全你提供的字符映射代码(原代码缺失switch语句,且4对应的字符有误):

// 预先定义二维数组存储每一位对应的字母串,假设最多处理10位输入
char letters[10][5]; // 每个字母串最长4字符+结束符

for (int i = 0; argv[1][i]; i++) {
    switch(argv[1][i]) {
        case '2':
            strcpy(letters[i], "abc");
            break;
        case '3':
            strcpy(letters[i], "def");
            break;
        case '4':
            strcpy(letters[i], "ghi");
            break;
        case '5':
            strcpy(letters[i], "jkl");
            break;
        case '6':
            strcpy(letters[i], "mno");
            break;
        case '7':
            strcpy(letters[i], "pqrs");
            break;
        case '8':
            strcpy(letters[i], "tuv");
            break;
        case '9':
            strcpy(letters[i], "wxyz");
            break;
        default:
            // 非法输入处理,设为空串
            letters[i][0] = '\0';
            break;
    }
}

接下来提供两种符合「无动态内存、无现成排序函数」要求的组合生成实现:


递归实现

核心逻辑

逐位递归构建组合:每处理一位,遍历该位的所有字符,将其追加到当前组合末尾,然后递归处理下一位;当处理完所有输入位时,将当前组合存入结果数组。

代码实现

// 预先定义结果数组:假设最多10位输入,对应最多4^10=1048576种组合,每个组合留11位空间(含结束符)
char result[1048576][11];
int count = 0; // 记录生成的组合数量

void generate_combinations(char letters[][5], int pos, int total_len, char current[], char result[][11], int *count) {
    if (pos == total_len) {
        // 组合完成,复制到结果数组
        strcpy(result[*count], current);
        (*count)++;
        return;
    }
    // 遍历当前位的所有字符
    for (int i = 0; letters[pos][i] != '\0'; i++) {
        current[pos] = letters[pos][i];
        current[pos + 1] = '\0'; // 确保字符串终止
        generate_combinations(letters, pos + 1, total_len, current, result, count);
    }
}

// 调用方式
int input_len = strlen(argv[1]);
char current[11] = {0}; // 临时存储当前正在构建的组合
generate_combinations(letters, 0, input_len, current, result, &count);

迭代实现

核心逻辑

基于乘法原理迭代扩展:初始时将第一位的所有字符作为初始组合;之后每处理一位,就将现有结果中的每个组合,分别与当前位的每个字符拼接,生成新的组合替换原结果(为避免覆盖未处理的组合,需从后往前更新)。

代码实现

// 预先定义结果数组,大小同递归版本
char result[1048576][11];
int count = 0;
int input_len = strlen(argv[1]);

// 初始化:第一位的所有字符作为初始组合
for (int i = 0; letters[0][i] != '\0'; i++) {
    result[count][0] = letters[0][i];
    result[count][1] = '\0';
    count++;
}

// 处理剩余的每一位
for (int pos = 1; pos < input_len; pos++) {
    int current_total = count; // 记录当前已有的组合数
    int char_count = strlen(letters[pos]); // 当前位的字符数量
    
    // 从后往前遍历现有组合,避免覆盖未处理的内容
    for (int i = current_total - 1; i >= 0; i--) {
        // 先复制原组合,生成char_count-1个新组合
        for (int j = 1; j < char_count; j++) {
            strcpy(result[count], result[i]);
            int combo_len = strlen(result[count]);
            result[count][combo_len] = letters[pos][j];
            result[count][combo_len + 1] = '\0';
            count++;
        }
        // 更新原组合,追加当前位的第一个字符
        int combo_len = strlen(result[i]);
        result[i][combo_len] = letters[pos][0];
        result[i][combo_len + 1] = '\0';
    }
}

注意事项

  • 预先定义的数组大小需足够覆盖最大可能的组合数,比如10位输入对应4^10=1048576种组合,需确保result数组的第一维度不小于该值
  • 若输入包含非法字符(非2-9),需提前过滤或处理,避免生成无效组合
  • 递归方式需注意栈溢出问题,输入长度超过15位时可能触发栈溢出,此时优先选择迭代实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:50:38