面试题:给定一个的电话号码,问生成的所有字母组合(容易记的电话号码)
题目: 有时候大家会很奇怪,为啥电话的键盘上会有ABC...这样的字母,尤其是在手机诞生之前就已经存在了。其实这些字母除了再发短信时有用,还有另一个作用是使电话号码容易记忆,这在美国比较的流行,比如拨打310-GINO便可向GINO订购比萨,其中GINO对应的就是4466。
哈,好玩吧。现在问题是这样的给定一个电话号码,比如123-4567或12345678,问其所有的字母组合。
比如:给定23,所有组合就是ad, ae, af, bd, be, bf, cd, ce, cf。
解答:
自己写了个递归实现。
大体思想是:
1. 建一个Mapping表,用于查找数字对应的字符。
2. 如果是一个数字,返回所有可能性的组合。
3. 如果多个数字,返回最后一个数字对应的组合跟前面已生产的字符串进行组合(笛卡尔乘积)
我的递归实现
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace NumberToWord
{
class Program
{
static void Main(string[] args)
{
foreach (String result in NumberToWord.ConvertNumberToWord("2543693"))
{
Console.WriteLine(result);
}
}
}
class NumberToWord
{
// Mapping Table
// PS: We may use Char[][] instead here.
// 0
// 1 2 3
// 4 5 6
// 7 8, 9
private static String[] NumberMappingTable = {
" ",
" ", "ABC", "DEF",
"GHI", "JKL", "MNO",
"PQRS", "TUV", "WXYZ"
};
public static List<String> ConvertNumberToWord(String number)
{
List<String> resultList = new List<string>();
// Return an empty list when input is empty.
if (String.IsNullOrEmpty(number.Trim()))
{
return resultList;
}
// Use regular expression to test if the input number is valid.
// Valid Characters are : 0123456789-*#
// Valid Number is like: 342-454-3432
// 4564334
// length is from 1 to 11
Regex reg = new Regex("([0-9*#-]){1,11}", RegexOptions.Compiled);
if (!reg.IsMatch(number))
{
throw new ArgumentException("Number is not well formatted!", "number", new ArgumentException());
}
// Replace '*', '-' and '#' with zero for looking up mapping table.
resultList = ConvertNumberToWordInternal(number.Replace('*', '0').Replace('#', '0').Replace('-', '0'));
return resultList;
}
private static List<String> ConvertNumberToWordInternal(String validNumber)
{
List<String> resultList = new List<string>();
// When it's the last (from left to right) number,
// iterate characters it mapped and write them into result List.
if (validNumber.Length == 1)
{
// Get mapped characters
String mappedChars = NumberMappingTable[Convert.ToInt32(validNumber)];
foreach (Char ch in mappedChars)
{
resultList.Add(ch.ToString());
}
}
// Otherwise we combine the characters mapped by the next (right to left) number
// with the List we already got from resolved numbers.
else
{
List<String> resolvedList = ConvertNumberToWord(validNumber.Substring(0, validNumber.Length - 1));
foreach (String resolvedString in resolvedList)
{
// The next number (from left to right) mapped characters
String nextNumMappedChars = NumberMappingTable[Convert.ToInt32(validNumber[validNumber.Length - 1].ToString())];
foreach (Char ch in nextNumMappedChars)
{
resultList.Add(resolvedString + ch.ToString());
}
}
}
return resultList;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace NumberToWord
{
class Program
{
static void Main(string[] args)
{
foreach (String result in NumberToWord.ConvertNumberToWord("2543693"))
{
Console.WriteLine(result);
}
}
}
class NumberToWord
{
// Mapping Table
// PS: We may use Char[][] instead here.
// 0
// 1 2 3
// 4 5 6
// 7 8, 9
private static String[] NumberMappingTable = {
" ",
" ", "ABC", "DEF",
"GHI", "JKL", "MNO",
"PQRS", "TUV", "WXYZ"
};
public static List<String> ConvertNumberToWord(String number)
{
List<String> resultList = new List<string>();
// Return an empty list when input is empty.
if (String.IsNullOrEmpty(number.Trim()))
{
return resultList;
}
// Use regular expression to test if the input number is valid.
// Valid Characters are : 0123456789-*#
// Valid Number is like: 342-454-3432
// 4564334
// length is from 1 to 11
Regex reg = new Regex("([0-9*#-]){1,11}", RegexOptions.Compiled);
if (!reg.IsMatch(number))
{
throw new ArgumentException("Number is not well formatted!", "number", new ArgumentException());
}
// Replace '*', '-' and '#' with zero for looking up mapping table.
resultList = ConvertNumberToWordInternal(number.Replace('*', '0').Replace('#', '0').Replace('-', '0'));
return resultList;
}
private static List<String> ConvertNumberToWordInternal(String validNumber)
{
List<String> resultList = new List<string>();
// When it's the last (from left to right) number,
// iterate characters it mapped and write them into result List.
if (validNumber.Length == 1)
{
// Get mapped characters
String mappedChars = NumberMappingTable[Convert.ToInt32(validNumber)];
foreach (Char ch in mappedChars)
{
resultList.Add(ch.ToString());
}
}
// Otherwise we combine the characters mapped by the next (right to left) number
// with the List we already got from resolved numbers.
else
{
List<String> resolvedList = ConvertNumberToWord(validNumber.Substring(0, validNumber.Length - 1));
foreach (String resolvedString in resolvedList)
{
// The next number (from left to right) mapped characters
String nextNumMappedChars = NumberMappingTable[Convert.ToInt32(validNumber[validNumber.Length - 1].ToString())];
foreach (Char ch in nextNumMappedChars)
{
resultList.Add(resolvedString + ch.ToString());
}
}
}
return resultList;
}
}
}
等有时间写个非递归实现。