为学论坛“每日一题”系列---数字和字母的映射

题目:

假设数字和26个字母一一对应,即1对应a,2对应b......26对应z,给定一个字符串,按字典序返回,它可能与哪些字母串对应。

例如“11”可以对应为aa,k,ak,ka,

输入:数字串

返回:字典序的全部可与之对应的字母串。


PS:不知道为什么,家里的网络又抽了,继不能上百度、VC驿站、hao123等网站之后,发现连为学论坛也不能上了,所以只能手打题目了,链接没法贴上来了。


我的思路:

对于这种找所有的情况,最直接做法就是用回溯法找出所有解了。

1、对于长度nLen == 1的数字串来说,数字串中的数字只能有一种操作,就是直接找出该数值对应的字母。

2、对于长度nLen >= 2的数字串中每一个数字来说,数字串中的数字可以有两种操作。一,与1相同,直接找出该数值对应的字母;二、先不找出该数值的字母,与数字串下一个数字或者上一个数字组成2位10进制数,并找出对应的数字的字母。

3、根据第2点,依次递归、回溯即可找出所有的情况。

PS:代码实现中用到了栈来保存中间的结果。


时间复杂度应该,不太会分析~~~




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

const int N = 1000 ;
char chStack[N] ; //栈,保存中间结果

void Map(char* szNums,char* szChars,int index,int bOn,int nPre,int sp,int nLen) ;
void MapNums2Chars(char* szNums,char* szChars) ;

int main(void)
{
	int i ;	
	char szNums[N] ;
	char szChars[27] ;

	freopen("in.txt","r",stdin) ;

	for(i = 0 ; i < 26 ; ++i)
	{
		szChars[i+1] = 'a' + i ;
	}

	while(scanf("%s",szNums) != EOF)
	{
		MapNums2Chars(szNums,szChars) ;
		printf("\n") ;
	}
	return 0 ;
}

void MapNums2Chars(char* szNums,char* szChars) 
{
	int nLen = strlen(szNums) ;	
	Map(szNums,szChars,0,0,0,-1,nLen) ;
}

//bOn ,0代表本层的操作是输出,1代表本层的操作是和上一层的数字组合成2位10进制数字并一起输出
void Map(char* szNums,char* szChars,int nIndex,int bOn,int nPre,int sp,int nLen) 
{
	if(nIndex >= nLen) //到数字串尽头,输出结果
	{
		chStack[++sp] = '\0' ;
		printf("%s\n",chStack) ;
		return  ;
	}
	else 
	{
		if(1 == bOn) //本层和上一层一起输出
		{
			chStack[++sp] = szChars[nPre*10 + (szNums[nIndex]-'0')] ; //和上一层一起输出
			Map(szNums,szChars,nIndex+1,0,szNums[nIndex]-'0',sp,nLen) ; //下一层单独输出

			chStack[sp] = '\0';
			return  ;
		}
		else if(0 == bOn) //本层单独输出
		{
			chStack[++sp] = szChars[szNums[nIndex]-'0'] ; //本层输出
			Map(szNums,szChars,nIndex+1,0,szNums[nIndex]-'0',sp,nLen) ;//下一层单独输出

			if(nIndex+1 < nLen && szNums[nIndex]-'0' < 3) //本层不输出,下一层和本层一起输出
			{
				chStack[sp] = '\0' ; //本层不输出
				sp-- ;
				Map(szNums,szChars,nIndex+1,1,szNums[nIndex]-'0',sp,nLen) ;
				chStack[++sp] = szChars[szNums[nIndex]-'0'] ; //恢复本层输出
			}

			chStack[sp] = '\0' ;
			return ;
		}
	}//else
}

我自己的测试数据:

1234
4321
112212
1312151267
11111
1111
111
1


PS:在论坛那里,看到别人用动态规则法解出来了,据说时间复杂度为O(n^2),太厉害了~~可能自己不太会动态规划的思想啊~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值