请教赶集网校招的一道笔试题

dkhghj 2013-10-29 12:44:13
大意是:a、b、c、...、z 分别与1、2、3、...、26对应,给出一串数字,输出所有可能的对应字母序列。如111可能对应aaa、ak、ka
...全文
399 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
光流溢彩 2013-10-29
  • 打赏
  • 举报
回复
前排占坐思考!
还有多远 2013-10-29
  • 打赏
  • 举报
回复
典型dfs:

#include <stdio.h>
#include <string.h>
#define MAX 500
/×
  a,b,...,z map to 1,2,...,26
  num is a string composed by 1~9
×/
char num[MAX], letter[MAX];
int lenOfNum;

void dfs(int nextOfLetter, int nextOfNum)
{
    int twoDigits;
    if(nextOfNum == lenOfNum){
	letter[nextOfLetter] = 0;
	puts(letter);
        return;
    }

    //one digit definitely matches a letter
    letter[nextOfLetter] = num[nextOfNum] - '1' + 'a';
    dfs(nextOfLetter+1, nextOfNum+1);

    //check if next two digits can match a letter
    if(nextOfNum+1 < lenOfNum){
	twoDigits = (num[nextOfNum] - '0') * 10 + (num[nextOfNum+1] - '0');
        if(twoDigits < 27){
	    letter[nextOfLetter] = twoDigits-1 + 'a';
	    dfs(nextOfLetter+1, nextOfNum+2);
	}
    }
}

int main()
{
    while(gets(num)){
	lenOfNum = strlen(num);
        dfs(0, 0);
    }
    return 0;
}
不知道dp能不能做, 用f(num, lenOfNum)表示num对应的字母串,则 f(num, lenOfNum) = f(num, i) + f(num+i, lenOfNum) 判重麻烦了就,记忆也是个问题
秃头披风侠 2013-10-29
  • 打赏
  • 举报
回复
递归,两个分支,分别处理1个字符和2个字符的情况。 回家再写个代码。
cy2015yc 2013-10-29
  • 打赏
  • 举报
回复
大概写了下,不确定是否正确。 很笨的办法,用递归 假设输入n各字符,则将其划分成两份[0,1) [1, n) 设[0,1)中的数字为n0 将[1,n)所有的组合情况保存起来 然后将第一个数字插入上一步骤中的所有组合的第一位 如果n0*10+其中某一个组合的第一位<26,则将这个组合的第一位替换成这个<26的数字

int explainInput(string s, int* a[])
{
	if (s.length() == 0)
	{
		return 0;
	}
	else if (s.length() == 1)
	{
		a[0] = new int[2];
		a[0][0] = 1;
		a[0][1] = s[0] - '0';
		return 1;
	}

	int ret = explainInput(s.substr(1), a);
	int head = s[0] - '0';
	int rise = 0;
	for (int n = 0; n < ret; ++n)
	{
		if (a[n] != nullptr)
		{
			a[ret+rise] = new int[a[n][0]+2];
			a[ret+rise][0] = a[n][0] + 1;
			a[ret+rise][1] = s[0] - '0';

			for (int k = 1; k <= a[n][0]; ++k)
			{
				a[ret+rise][k+1] = a[n][k];
			}
			++rise;

			if ((a[n][1] <= 6 && head == 2) || (a[n][1] < 10 && head == 1))
			{
				a[ret+rise] = new int[a[n][0]+1];
				a[ret+rise][0] = a[n][0];
				a[ret+rise][1] = head * 10 + a[n][1];
				for (int k = 2; k <= a[n][0]; ++k)
				{
					a[ret+rise][k] = a[n][k];
				}
				++rise;
			}
			delete[] a[n];
			a[n] = nullptr;
		}
	}

	return ret+rise;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int* a[100];

	int ret = explainInput("11111", a);
	for (int j = 0; j < ret; ++j)
	{
		int* arr = a[j];
		if (arr == nullptr)
		{
			continue;
		}
		for (int i = 1; i <= arr[0]; ++i)
		{
			cout << arr[i] << " ";
		}
		delete[] arr;
		cout << endl;
	}
}
XJMTXWDS 2013-10-29
  • 打赏
  • 举报
回复
3楼说的对,分成两种情况
fishion 2013-10-29
  • 打赏
  • 举报
回复
用递归就很好做了
hangang7403 2013-10-29
  • 打赏
  • 举报
回复
用递归做,第一层用1位 和2位划分,然后两种情况分别做递归
lm_whales 2013-10-29
  • 打赏
  • 举报
回复
优点像台阶问题
lm_whales 2013-10-29
  • 打赏
  • 举报
回复
1 位或者两位 对应一个字母。
  • 打赏
  • 举报
回复
估计得用递归

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧