3.2 电话号码对应的英语单词
2015-08-27 18:24
399 查看
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, 所以请大家指出!
相关文章推荐
- 《编程之美》
- 2012年终碎语,编程之美
- 失业在家的学习笔记-第二天
- 编程之美2015初赛A
- 编程之美初赛B
- 程序员编程艺术3:寻找最小的k个数
- 编程之美2013全国挑战赛资格赛第1题
- 编程之美2013全国挑战赛资格赛第3题
- 编程之美3.8:求二叉树节点的最大距离
- 瓷砖覆盖地板问题
- Best Time to Buy and Sell Stock
- 编程之美2014格格取数
- 编程之美——象棋将帅问题
- 编程之美——烙饼排序问题
- 连连看游戏判断两个块是否可以消去,并计算最小转弯数
- 《编程之美》——中国象棋将帅问题
- 《编程之美》——求二叉树中节点的最大距离(非递归)
- 《编程之美》——求二叉树中节点的最大距离(非递归)
- 《编程之美》——中国象棋将帅问题
- 连连看游戏判断两个块是否可以消去,并计算最小转弯数