不使用动态内存,如何生成手机键盘字符组合的二维数组?
生成电话号码字母组合(无动态内存限制版)
首先修正并补全你提供的字符映射代码(原代码缺失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
相关产品推荐
相关产品推荐

