编程之美:3.2电话号码对应英语单词

原始问题如下:手机上面的数字键均对应了几个字符,譬如2对应了a,b,c。问题是当输入一段数字后,求出所有可能的字符组合,(可以想象一下发短信时候的状况,每当按几个数字键后,均给出可能的汉语拼音,当然这个要求就更高了,本题只要求给出所有可能的组合)。
举个例子输入4,2键后,则给出GA,GB,GC,HA,HB,HC,IA,IB,IC组合。

#include<iostream>
#include<string>
#include<map>

using namespace std;

typedef map<int, string> numAlpMap;
numAlpMap myMap;


int ansNum = 0;
//anser用于存放对应数字目前所代表的字符在其所代表的字符集中的位置
int answer[100];


void init(){
    myMap[0] = "";
    myMap[1] = "";
    myMap[2] = "abc";
    myMap[3] = "def";
    myMap[4] = "ghi";
    myMap[5] = "jkl";
    myMap[6] = "mno";
    myMap[7] = "pqrs";
    myMap[8] = "tuv";
    myMap[9] = "wxyz";
}
/*
若电话号码为N位,则需要n个for循环,因此若为3位号码,则需要3次循环
*/
const void function1(string tel)
{
    for (int i = 0; i < myMap[tel[0] - '0'].length(); i++)
    {
        for (int j = 0; j < myMap[tel[1] - '0'].length(); j++)
        {
            for (int k = 0; k < myMap[tel[2] - '0'].length(); k++)
            {
                cout << myMap[tel[0] - '0'][i] << myMap[tel[1] - '0'][j] <<myMap[tel[2] - '0'][k];
                cout << endl;
            }
        }
    }

    return;
}

/*
该方法是对function1的提升,是将所有分支从0到len-1进行标号,
然后每次计算不同分支的值
*/
const void function2(string tel)
{
    int len = tel.length();

    int count = 1;
    //该段程序实现了anwer从00000到nnnnnn的全部情况计算,为核心程序
    while (true)
    {

        for (int j = 0; j < len; j++)
        {
            cout << answer[j];
        }
        cout << endl;

        for (int i = 0; i < len; i++)
        {
            int num = tel[i] - '0';
            cout << myMap[num][answer[i]];
        }

        cout << count++ << endl;
        //k从answer的末尾开始遍历
        int k = len - 1;
        while (k >= 0)
        {
            if (answer[k] < myMap[tel[k]-'0'].length()-1)
            {
                answer[k]++;
                break;
            }
            else
            {
                answer[k] = 0;
                k--;
            }
        }
        if (k < 0)
        {
            break;
        }
    }
}
/*
递归查找,将answer的所有情况进行遍历,并在索引index为len时将情况进行输出,
index说明对电话号码的第几位进行循环
n为电话号码的位数
tel为电话号码
*/
void recursiceSearch(string tel, int* answer, int index, int n)
{
    if (index == n)
    {
        for (int i = 0; i < n; i++)
        {
            int num = tel[i] - '0';
            cout << myMap[num][answer[i]];
        }
        cout << ++ansNum << endl;
    }
    for (answer[index] = 0; answer[index] < myMap[tel[index] - '0'].length(); answer[index]++)
    {
        recursiceSearch(tel, answer, index + 1, n);
    }
}
int main()
{

    init();
    string tel;
    while (cin >> tel){
        memset(answer, 0, tel.length()*sizeof(int));
        //function1(tel);
        function2(tel);
        //recursiceSearch(tel, answer, 0, tel.length());
    }
    return 0;

}

function2的核心代码不是太好理解,可以对着打印的answer数组进行理解,function2程序运行结果如下:
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值