Может ли кто-нибудь поделиться чистой версией класса Coder из выступления Одерского на Scala Days 2011? - PullRequest
5 голосов
/ 25 декабря 2011

Мартин Одерский выступил с основным докладом на Scala Days 2011. В нем он представил впечатляющее решение известной проблемы кодировщика фраз телефонного номера, использованной в статье Лютца Пречелта «Эмпирическое сравнение семи языков программирования» в IEEE Computer 33. Я пыталсявзять код из PDF, но результат был полон неразрывных пробелов, от которых трудно избавиться.

Кроме того, в данном решении есть некоторые странные вещи, такие как типы, явно упомянутые, когда ониможно было бы сделать вывод, и Map со значениями List [String] по умолчанию было бы присвоено значение 0. И это просто класс;это не исполняемый файл.

Есть ли у кого-нибудь готовая, очищенная версия этого примерного кода?

С основным докладом и слайдами можно ознакомиться здесь:

http://days2011.scala -lang.org / узел / 138/270

Ответы [ 2 ]

4 голосов
/ 25 декабря 2011

Вот очищенная версия класса 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, чтобы взять и сбросить за один раз.

3 голосов
/ 25 декабря 2011

Имеется гист по retronym и даже GWT framework для запуска этого примера Гжегожем Коссаковским.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...