Вот очищенная версия класса Coder вместе с классом CoderTest, который вы выполняете следующим образом: первый аргумент - это номер телефона, который нужно кодировать, а остальные - слова в словаре:
$ scala CoderTest 7225276257 let us see if scala rocks is in the output
Set(scala rocks)
В этих выходных данных говорится, что для данного номера телефона и словаря единственной найденной кодировкой является пара слов "скала скал".
Вот тестовый драйвер:
object CoderTest extends App {
val digits::words = args.toList
println( new Coder(words) translate digits )
}
А вот и сам класс Coder. Я изменил некоторые идентификаторы и комментарии, чтобы сделать их более понятными для себя.
class Coder( words: List[String] ) {
// In this code "num" means a string of digits, e.g. "834921".
val digitToLetters = Map(
'2' -> "ABC", '3' -> "DEF" , '4' -> "GHI", '5' -> "JKL",
'6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ"
)
// Invert digitToLetters to give a map from chars 'A'..'Z' to '2'..'9'.
val letterToDigit =
for ( (digit,itsLetters) <- digitToLetters; letter <- itsLetters )
yield ( letter -> digit )
// Maps a word to the digit string it can represent.
def wordToNum( word: String ) = word.toUpperCase map letterToDigit
// Map from digit string to words in our dictionary that represent it.
// e.g. 5282 -> List( Java, Kata, Lava, ... )
val numToWords = ( words groupBy wordToNum ) withDefaultValue List()
// Maps a digit string to all phrases (lists of dictionary words)
// that represent it.
def numToPhrases( num: String ): Set[ List[String] ] =
if ( num.isEmpty )
Set( List() )
else (
for { splitPoint <- 1 to num.length
word <- numToWords ( num take splitPoint )
phrase <- numToPhrases( num drop splitPoint )
} yield word::phrase
).toSet
// Maps a number to the set of all word phrases that can represent it.
def translate( num: String ) = numToPhrases(num) map ( _ mkString " " )
}
Помните, однако, что на самом деле хорошей идеей является указание возвращаемых типов методов, которые являются частью общедоступного API. И теперь вы можете использовать splitAt, чтобы взять и сбросить за один раз.