C语言电话号码的字母组合

该文章描述了一个C语言程序,它接受一个只包含2-9的数字字符串,并根据电话键盘的字母映射关系,生成所有可能的字母组合。程序使用递归方法遍历每个数字对应的字母集,对于非法输入(如包含0或1的数字),程序会给出错误提示。示例输入5678,程序将输出所有可能的4个字母组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

电话号码的字母组合,给定一个仅包含数字2-9的字符串,返回所有它能表示的字母组合。
答案可以按任意顺序返回。给出数字到字母的映射如下(与电话按键相同)。
注意0和1不对应任何字母。

/*
电话号码的字母组合,给定一个仅包含数字2-9的字符串,返回所有它能表示的字母组合。
答案可以按任意顺序返回。给出数字到字母的映射如下(与电话按键相同)。
注意0和1不对应任何字母。
例:输入23,则输出ad,ae,af,bd,be,bf,cd,ce,cf
全文以输入5678为例
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char digits[10];	//键盘输入的数字(5678)
char result[10];	//每一层循环得到的一个字母组成的输出值(gmpt等)
char *letters[10];	//letterMap里数字对应的字母组(例:5对应jkl)
int len[5];			//存放letters里每个字母组的长度(jkl长3,pqrs对应4)
int m = 0;				//计数,方便查看循环次数和得到的结果数

void cycle(char *digits, int index);

char *letterMap[10] = {"",     //0
                       "",     //1
                       "abc",  //2
                       "def",  //3
                       "ghi",  //4
                       "jkl",  //5
                       "mno",  //6
                       "pqrs", //7
                       "tuv",  //8
                       "wxyz", //9
                      };

int main() {
	printf("输入一个用2-9之间的数字组成的4位以内的数:");
	scanf("%s", digits);
	for (int i = 0; i < strlen(digits); i++) {
		int n = digits[i] - '0';		//把输入的数中的每一个数字转为整型
		//判断输入的数字中是否输入了1和0
		if (n < 2) {
			printf("输入的第%d个数不合法!\n", i + 1);
			return 1;
		}
		letters[i] = letterMap[n];		//得到每个数字对应的字母组
		len[i] = strlen(letters[i]);		//每个字母组的长度
	}
	cycle(digits, 0);
	return 0;
}

void cycle(char *digits, int index) {
	char *ltr;		//指向字母组
	//index=digits时,每个字幕组都循环了,退出取值
	if (index == strlen(digits)) {
		printf("%d:%s\n", m++, result);
	}
	for (int j = 0; j < len[index]; j++) {
		ltr = letters[index];	//取第index数字对应的字母组(第2个数字6对应mno)
		result[index] = ltr[j];
		cycle(digits, index + 1);
	}
}
### 使用C语言实现电话号码字母组合 为了生成给定数字串 `digits` 所有可能表示的字母组合,可以采用回溯算法。该方法通过递归构建所有可能的结果字符串,并将其保存到最终结果集中。 #### 定义映射关系 首先定义一个数组用于存储每个数字所对应的字符集: ```c const char* letters[] = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; ``` 此部分代码建立了从数字到其关联字符序列之间的桥梁[^1]。 #### 主函数设计 接下来创建主处理逻辑,在这里初始化必要的变量并启动递归过程: ```c void backtrack(char* digits, int index, char* path, char** result, int* returnSize); char** letterCombinations(char* digits, int* returnSize) { if (strlen(digits) == 0) { *returnSize = 0; return NULL; } // 动态分配足够的内存来容纳所有的组合情况 *returnSize = pow(4,strlen(digits)); char **result = malloc(*returnSize * sizeof(char *)); // 初始化路径缓冲区 char path[strlen(digits)+1]; memset(path, '\0', strlen(digits)+1); // 开始回溯搜索 int count = 0; backtrack(digits, 0, path, result, &count); *returnSize = count; return result; } ``` 上述代码片段展示了如何设置初始条件以及调用辅助函数完成核心功能[^2]。 #### 回溯函数实现 最后是具体的回溯操作,负责逐位填充当前正在形成的候选解直到形成完整的单词为止;一旦发现符合条件则加入答案列表之中: ```c void backtrack(char* digits, int index, char* path, char** result, int* returnSize){ if(index >= strlen(digits)){ strcpy(result[*returnSize],path); (*returnSize)++; return ; } const char* options = letters[digits[index]-'0']; for(int i=0;i<strlen(options);i++){ path[index]=options[i]; backtrack(digits,index+1,path,result,returnSize); } } ``` 这段实现了基于当前位置尝试每一种可能性并向更深一层继续探索的过程,直至达到终止状态时记录下有效方案[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值