3.2 电话号码对应的英语单词

1. 前言

本文的一些图片, 资料 截取自编程之美

2. 问题描述

这里写图片描述

3. 问题分析

一个数字, 对应一个字符数组, 这个问题其实就是穷举出这个数字数组能够表示的所有的字符的拼凑, 然后找出为单词的序列
这里 我只做了穷举 “数字数组 -> 字符序列”

解法 : 使用一个pos数组, 来表示使用第i个数字的第pos[i]个字符, 然后设计一个累增的方法incPos来控制pos的增长, 至于迭代方式 可以选用循环, 也可以使用递归

这里的wordsToNumber01 表示输入一个字符序列, 获取其数字表示, 比较简单 这里就不说了

4. 代码

/**
 * file name : Test04PhoneNumberMapWords.java
 * created at : 9:38:08 AM May 27, 2015
 * created by 970655147
 */

package com.hx.test04;

public class Test04PhoneNumberMapWords {

    // 枚举出手机号码 到字符的所有映射
    public static void main(String []args) {

        int[] numberLen = new int[] {0, 0, 3, 3, 3, 3, 3, 4, 3, 4 };  
        char[][] numberMap = initNumberMap(numberLen);

        int[] number = new int[] {9, 2, 3 };
        int[] pos = new int[] {0, 0, 0 } ;


//      phoneNumberMapWords01(numberMap, numberLen, number, pos);
        phoneNumberMapWords02(numberMap, numberLen, number, pos);

        char[] str = new char[] {'z', 'c', 'e' };
        int[] dict = initDict(numberLen);
        wordsToNumber01(dict, str);
    }

    // 思路 : 更新pos的最后一位  如果需要进位   在循环更新pos最后一位之前的数据
    // numberMap 表示数字到字母的映射, numberLen表示每一个映射的长度
    // number 表示号码是多少, pos表示当前字符在对应号码的索引
    public static void phoneNumberMapWords01(char[][] numberMap, int[] numberLen, int[] number, int[] pos) {
        int lastOne = pos.length - 1;
        boolean isEnd = false;

        while(!isEnd ) {    
            for(int i=0; i<number.length; i++) {
                Log.logWithoutLn(numberMap[number[i]][pos[i]] + " ");
            }
            Log.enter();

            // 更新pos
            isEnd = incPos(numberLen, number, pos);
        }

    }

    // 递归实现  不过本质基本一样[尾递归会优化为循环]
    public static void phoneNumberMapWords02(char[][] numberMap, int[] numberLen, int[] number, int[] pos) {

        for(int i=0; i<number.length; i++) {
            Log.logWithoutLn(numberMap[number[i]][pos[i]] + " ");
        }
        Log.enter();

        boolean isEnd = incPos(numberLen, number, pos);
        if(!isEnd ) {
            phoneNumberMapWords02(numberMap, numberLen, number, pos);
        }

    }

    // 利用字母到数字的映射  映射str的每一个字符
    public static void wordsToNumber01(int[] dict, char[] str) {
        int[] res = new int[str.length];

        int a = 'a';
        int idx = 0;
        for(int i=0; i<str.length; i++) {
            int idx0 = str[i] - a;
            res[idx ++] = dict[idx0];
        }

        Log.logWithoutPosition(res);
    }

    // 递增pos  如果到达了最大值   则返回false
    private static boolean incPos(int[] numberLen, int[] number, int[] pos) {
        int lastOne = pos.length - 1;

        pos[lastOne] ++;    
        int idx = lastOne;
        while(pos[idx] == numberLen[number[idx] ] ) {
            if(idx == 0) {
                return true;
            }

            pos[idx] = 0;
            idx --;
            pos[idx] ++;
        }

        return false;
    }

    // 初始化数字到字母的映射表
    private static char[][] initNumberMap(int[] numberLen) {
        char[][] numberMap = new char[10][4];
        char idx = 'a';

        for(int i=0; i<numberLen.length; i++) {
            for(int j=0; j<numberLen[i]; j++) {
                numberMap[i][j] = idx++;
            }
        }

        return numberMap;
    }

    // 初始化字符到数字的映射表
    private static int[] initDict(int[] numberLen) {
        int[] res = new int[26];

        int a = 'a', z = 'z';
        int idx = 0, cnt = 0;
        for(int i=a; i<=z; i++) {
            while(cnt == numberLen[idx]) {
                idx ++;
                cnt = 0;
            }

            res[i-a] = idx;

            cnt ++;
        }

        return res;
    }

}

5. 运行结果

这里写图片描述

6. 总结

这个问题不是很难, 但是设计方法的时候, 需要注意一些细节的问题

注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值