您的位置:首页 > 其它

每日一题(82) - 电话号码对应的英语单词

2013-08-27 15:44 302 查看
题目和思路来自编程之美

题目:

电话的号码盘一般可以用于输入字母,而且一个数字可以对应多个或者0个字母。如用2可以输入A、B、C,用3可以输入D、E、F等。

给出一个号码,它可以对应许多个字母组合。如号码5869872,它对应的字母组合可以是JTMWTPTA、JTMWTB······

问题(1)给出一个电话号码,设计程序,从该电话号码对应的这些字母组合中,找到一个有意义的单词来表述一个电话号码。

举例:单词"computer"来描述号码26678837。

问题(2)对于一个号码,是否可以用一个单词代表?(否)怎样才是最快的方法?

综合这两个问题,其实就是找出最快的方法,使得找到一个有意义的单词与数字对应?

思路:

方法(1)对字母集合进行深搜 + 字典匹配

<1>直接对每一个数字对应的字母集合进行深搜,类似元素的组合求出所有字母集合

<2>对每一种组合都与字典匹配,有意义则输出

代码:这里指给出深搜求字母组合的递归代码

#include <iostream>
#include <assert.h>
using namespace std;

void Perm(char strSet[10][10],int nArrTeleNum[],int nLen,int nCur,int nPos,char strWord[])
{
	if (nCur == nLen)
	{
		for (int i = 0;i <= nPos;i++)
		{
			cout<<strWord[i];
		}
		cout<<endl;
		return;
	}
	char* pStr = strSet[nArrTeleNum[nCur]];
	int nCurStrLen = strlen(pStr);
	
	if (nCurStrLen == 0)
	{
		Perm(strSet,nArrTeleNum,nLen,nCur + 1,nPos,strWord);
	}
	else
	{
		for (int i = 0;i < nCurStrLen;i++)
		{
			strWord[nPos] = pStr[i];
			Perm(strSet,nArrTeleNum,nLen,nCur + 1,nPos + 1,strWord);
		}
	}
}

int main()
{
	int nArrTeleNum[10];//存放电话号码
	int nLen;//本次输入电话号码个数
	char strWord[10];//产生的单词集合
	char strSet[10][10]=
	{
		"","","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"
	};

	cin>>nLen;
	for (int i = 0;i < nLen;i++)
	{
		cin>>nArrTeleNum[i];
		assert(nArrTeleNum[i] >= 0 && nArrTeleNum[i] <= 9);
	}

	Perm(strSet,nArrTeleNum,nLen,0,0,strWord);
	system("pause");
	return 1;
}
迭代代码:

书中给出了一个不确定循环个数的代码,挺有意思。可以一看。

#include<iostream>
using namespace std;

const int MaxLength = 9;
char c[10][10] = {"", "", "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"};
int total[10] = {0,0,3,3,3,3,3,4,3,4};

int main()
{
	int number[MaxLength] = {3,4,5}; //本例输入数字3,4,5
	int answer[MaxLength] = {0};
	int len = 3;

	while(true)
	{
		for(int i = 0; i < len; i++)//每当有一个数字改变了,都是一种排列,直接输出
			printf("%c", c[number[i]][answer[i]]);
		printf("\n");

		int k = len - 1;//其中某一位改变后,都从最后一个数开始重新赋值,形成新排列
		while(k >= 0)
		{
			if(answer[k] < total[number[k]] - 1)//其中某一位改变后,也是一种新排列,不再继续循环
			{
				answer[k]++;
				break;
			}
			else//第k位的数已经全部放完,此时需要设置第k - 1位。
			{
				answer[k] = 0;//为了下一次下标++后不越界,需要把第k位置0
				k--;
			}
		}
		if(k < 0)//所有元素均处理完了。
			break;
	}
	return 0;
}


方法(2)离线求出每一个数字组合对应的字母组合 +在线字典匹配

这里代码不再给出。

方法(3)字典单词转化为数字 + 与给出数字进行匹配

思路:把字典中的单词转换为数字,之后把转换后的数字与给出的数字进行匹配。

这里代码不再给出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: