问题
I'm currently trying to implement the Telephone word generator. I looked all around the web for something that I could use and this is what I found.
I found this implementation in C#:
public static void printPhoneWords(int[] number) {
char[] output = new char[number.length];
printWordsUtil(number,0,output);
}
static String[] phoneKeys= new String[]{"0", "1", "ABC", "DEF", "GHI", "JKL",
"MNO", "PQRS", "TUV", "WXYZ"};
private static void printWordsUtil(int[] number, int curDigIndex, char[] output) {
// Base case, if current output word is done
if (curDigIndex == output.length) {
System.out.print(String.valueOf(output) + " ");
return;
}
// Try all 3-4 possible characters for the current digit in number[]
// and recurse for the remaining digits
char curPhoneKey[] = phoneKeys[number[curDigIndex]].toCharArray();
for (int i = 0; i< curPhoneKey.length ; i++) {
output[curDigIndex] = curPhoneKey[i];
printWordsUtil(number, curDigIndex+1, output);
if (number[curDigIndex] <= 1) // for 0 or 1
return;
}
}
public static void main(String[] args) {
int number[] = {2, 3, 4};
printPhoneWords(number);
System.out.println();
}
Now, I tried to implement it in Swift, but I'm getting a few issues..
var pinDict = [2:"abc", 3:"def", 4:"ghi", 5:"jkl", 6:"mno", 7:"pqrs", 8:"tuv", 9:"wxyz"]
func printWordsUtil(number: [Int], curDigIndex: Int, output: Array<Character>) {
var curPhoneKey:Array<Character> = []
curPhoneKey = pinDict[number[curDigIndex]]
for var i = 0; i < curPhoneKey.count; i++ {
output[curDigIndex] = pinDict[i]
printWordsUtil(number, curDigIndex+1, output)
if(number[curDigIndex] <= 1) {
return
}
}
}
func printPhoneWords(number: [Int]) {
var output:Array<Character> = []
printWordsUtil(number,0,output)
}
func main() {
var number = [2, 2, 7, 3]
printPhoneWords(number)
}
I'm getting my errors here:
curPhoneKey = pinDict[number[curDigIndex]]
//'(Int, String)'
not convertible to'Array<Character>'
Not sure how to solve this...output[curDigIndex] = pinDict[i]
//'@lvalue $T8'
is not identical to 'Character'
Any ideas on how to have this implementation working in Swift?
Ok, so at the moment I have this:
comparisonArray.append(dictionary[a!])
comparisonArray.append(dictionary[b!])
comparisonArray.append(dictionary[c!])
comparisonArray.append(dictionary[d!])
func combos<T>(var array: Array<T>, k: Int) -> Array<Array<T>> {
if k == 0 { return [[]] } if array.isEmpty { return [] }
let head = [array[0]]
let subcombos = combos(array, k - 1)
var ret = subcombos.map {head + $0}
array.removeAtIndex(0)
ret += combos(array, k)
return ret
}
combos(comparisonArray, 4)
The comparison array is ["ABC, "DEF", "DEF, "PQRS"]
. Now, how do you permute every letter in each combination on it's own instead of permuting the element, so it looks like this? ["A", "D", "D", "P"]
, ["B", "D", "D", "P"]
? THANKS!
回答1:
You will need this string extension:
extension String {
subscript (index:Int) -> String { return String(Array(self)[index]) }
}
First lets convert the Int Array to a String Array
func intArrayToStringArray(number: [Int]) -> [String] {
if number.isEmpty { return [] }
let keyboard = ["0","1","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"] var result:[String] = []
for i in 0..<number.count {
result.append(keyboard[number[i]])
}
return result
}
let firstStep = intArrayToStringArray([2,2,7,3]) // ["abc", "abc", "pqrs", "def"]
Then we will need to nest one loop for each number and pick the letters using the index combination of them, join them using string interpolation and append it to the output array.
func secontStep(input:[String]) -> [String] {
var output:[String] = []
for w in 0..<countElements(input[0]) {
for x in 0..<countElements(input[1]) {
for y in 0..<countElements(input[2]){
for z in 0..<countElements(input[3]){
output.append("\(input[0][w])\(input[1][x])\(input[2][y])\(input[3][z)")
}
}
}
}
return output
}
let wordsArray = secontStep(firstStep) // ["aapd", "aape", "aapf", "aaqd", "aaqe", "aaqf", "aard", "aare", "aarf", "aasd", "aase", "aasf", "abpd", "abpe", "abpf", "abqd", "abqe", "abqf", "abrd", "abre", "abrf", "absd", "abse", "absf", "acpd", "acpe", "acpf", "acqd", "acqe", "acqf", "acrd", "acre", "acrf", "acsd", "acse", "acsf", "bapd", "bape", "bapf", "baqd", "baqe", "baqf", "bard", "bare", "barf", "basd", "base", "basf", "bbpd", "bbpe", "bbpf", "bbqd", "bbqe", "bbqf", "bbrd", "bbre", "bbrf", "bbsd", "bbse", "bbsf", "bcpd", "bcpe", "bcpf", "bcqd", "bcqe", "bcqf", "bcrd", "bcre", "bcrf", "bcsd", "bcse", "bcsf", "capd", "cape", "capf", "caqd", "caqe", "caqf", "card", "care", …, "cbqe", "cbqf", "cbrd", "cbre", "cbrf", "cbsd", "cbse", "cbsf", "ccpd", "ccpe", "ccpf", "ccqd", "ccqe", "ccqf", "ccrd", "ccre", "ccrf", "ccsd", "ccse", "ccsf"]
the opposite would be like this:
func stringToArray(var number: String) -> [Int] {
if number == "" { return [] }
number = number.lowercaseString
var result:[Int] = []
for i in 0..<countElements(number) {
if number[i] == "0" { result.append(0) }
if number[i] == "1" { result.append(1) }
if number[i] == "2" || number[i] == "a" || number[i] == "b" || number[i] == "c" { result.append(2) }
if number[i] == "3" || number[i] == "d" || number[i] == "e" || number[i] == "f" { result.append(3) }
if number[i] == "4" || number[i] == "g" || number[i] == "h" || number[i] == "i" { result.append(4) }
if number[i] == "5" || number[i] == "j" || number[i] == "k" || number[i] == "l" { result.append(5) }
if number[i] == "6" || number[i] == "m" || number[i] == "n" || number[i] == "o" { result.append(6) }
if number[i] == "7" || number[i] == "p" || number[i] == "q" || number[i] == "r" || number[i] == "s" { result.append(7) }
if number[i] == "8" || number[i] == "t" || number[i] == "u" || number[i] == "v" { result.append(8) }
if number[i] == "9" || number[i] == "w" || number[i] == "x" || number[i] == "y" || number[i] == "z" { result.append(9) }
}
return result
}
stringToArray("1800HELLO") // [1, 8, 0, 0, 4, 3, 5, 5, 6]
stringToArray("1800hello") // [1, 8, 0, 0, 4, 3, 5, 5, 6]
来源:https://stackoverflow.com/questions/27367770/telephone-word-generator-implementation-in-swift-based-on-c-sharp-program