《編程之美》 - 3.2 電話號碼對應英文單詞 (發現書上遞歸解法的錯誤)

/*  題目(改動):
電話的號碼潘通常能夠用於輸入字母。如用 2 能夠輸入A、B、C,用 3 能夠輸入 D 、E、F等。
是否能夠根據這樣的對應關係設計一個程序,輸出 所輸入數字對應的全部字母的組合
*/

 

/* 代碼以下 : */
#include <iostream>
#include <string>
using namespace std;
void NumToWord(string str);
int main()
{
    string str;
    cout << "輸入數字:";
    cin  >>str;

    NumToWord(str);

    return 0;

}

void NumToWord(string str)
{
    //準備工做
    char c[10][10] = {

        "",                  // 0
        "",                  // 1
        "ABC",              // 2
        "DEF",              // 3
        "GHI",              // 4
        "JKL",              // 5
        "MNO",              // 6
        "PQRS",              // 7
        "TUV",               // 8
        "WXYZ"              // 9
    };

    //每一個數字對應有幾個英文字母
    char total[10] = {0,0,3,3,3,3,3,4,3,4};

    // 數組長度
    int length = str.length();

    // number[i] 爲輸入的數字的數組
    // answer[i] 爲 number[i] 所對應的數字所對應的第幾個英文字母,初始化爲第0個
    int number[100];
    int answer[100];

    //初始化兩個數組
    for(int i = 0;i < length;i++)
    {
        number[i] = str[i] - '0';
        answer[i] = 0;
    }

    while(true)
    {

        for(int i = 0;i < length;i++)
            cout << c[number[i]][answer[i]];  
        cout <<endl;

        int k = length - 1;
        while(k >= 0)
        {
            /* 檢查最後一位的字母是否已輸出完 */
            if(answer[k] < total [ number[k] ] - 1 )
            {
                answer[k] ++;
                break;
            }
            else
            {
                /* 輸出完的話將其置 0 ,將其上一位 的輸出改變 */
                answer[k] = 0;
                k--;
            }
        }
        if(k < 0 )
            break;
    }

    }

 

假設輸入爲 234 ,從輸出應該能夠幫助你理解上面的代碼ios

/*
輸入數字:234
ADG
ADH
ADI
AEG
AEH
AEI
AFG
AFH
AFI
BDG
BDH
BDI
BEG
BEH
BEI
BFG
BFH
BFI
CDG
CDH
CDI
CEG
CEH
CEI
CFG
CFH
CFI
請按任意鍵繼續. . .
*/
/* 書上使用的遞歸算法 
   只要輸入中包含0和1兩個不包含字母的值
   就會失靈,中間循環斷掉
   一個很差用的解決方法:
   把下面數組的前兩位變成1
   char total[10] = {0,0,3,3,3,3,3,4,3,4};
   即
   char total[10] = {1,1,3,3,3,3,3,4,3,4};
*/

#include <iostream>
#include <string>
using namespace std;
void NumToWord(int* number,int* answer,int index,int n);
    

    // number[i] 爲輸入的數字的數組
    // answer[i] 爲 number[i] 所對應的數字所對應的第幾個英文字母,初始化爲第0個
    int number[100];
    int answer[100];
    int length;
    char total[10] = {0,0,3,3,3,3,3,4,3,4};
    char c[10][10] = {

        "",                  // 0
        "",                  // 1
        "ABC",              // 2
        "DEF",              // 3
        "GHI",              // 4
        "JKL",              // 5
        "MNO",              // 6
        "PQRS",              // 7
        "TUV",               // 8
        "WXYZ"              // 9
    };
int main()
{
    string str;
    cout << "輸入數字:";
    cin  >>str;

    /* 準備 */
    
    //每一個數字對應有幾個英文字母
    

    // 數組長度
    length = str.length();

    //初始化兩個數組
    for(int i = 0;i < length;i++)
    {
        number[i] = str[i] - '0';
        answer[i] = 0;
    }
    NumToWord(number,answer,0,length);
    return 0;
}

void NumToWord(int* number,int* answer,int index,int n)
{

    if(index == n)
    {
        for(int i = 0;i < n;i++)
            cout << c[number[i]][answer[i]];
        cout << endl;
        return;
    }
    for(answer[index] = 0;
        answer[index] < total[number[index]];
        answer[index]++)
    {
        NumToWord(number,answer,index+1,n);

    }

}
相關文章
相關標籤/搜索