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

来源:互联网 发布:淘宝上的装修公司 编辑:程序博客网 时间:2024/04/29 14:48

题目:

假设数字和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}

我自己的测试数据:

1234432111221213121512671111111111111


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

原创粉丝点击