【问题标题】:Clojure: using strings with list comprehensionsClojure:使用带有列表推导的字符串
【发布时间】:2016-02-01 19:37:43
【问题描述】:

我正在尝试编写 Martin Odersky 的函数式编程课程中第 6.7 课的 clojure 版本。原版是用 Scala 编写的。

这个概念是获取一个电话号码(作为一个字符串)并在给定单词字典的情况下生成一个可能的短语列表。

因此,translate("7225247386") 会产生短语“Scala 很有趣”

这是Gist with the full Scala version。

这是我的attempt using Clojure

最终的“编码”函数出现问题 Scala 版本是

def encode(number: String): Set[List[String]] =
if (number.isEmpty) Set(List())
else {
    for {
        split <- 1 to number.length
        word <- wordsForNum(number take split)
        rest <- encode(number drop split)
        } yield word :: rest
}.toSet

使用我的 Clojure 版本

    (defn encode
      "Takes a number as a string. Returns all the different ways to encode that number as a list of words"
  [number]
  (if (empty? number)
    (vector)             
    (for [split (range 0 (count number))      
          word  (words-from-number (subs number 0 split)) 
          remainder (encode (subs number split))]    
      (concat word remainder))))

问题似乎是字符串不断转换为字符列表;这就是为什么我使用(subs number 0 split) 而不是(take split number)

上面的一个版本只找到第一个单词似乎是在正确的轨道上......

    (defn encode
  [number]
  (for [split (range 0 (count number))
        word (words-from-number (subs number 0 split))]
    word))

(encode "7225247386") => ("pack" "rack" "sack" "Scala")

...但是用剩余的数字字符串添加对“编码”的递归调用只会返回一个空列表。

任何建议将不胜感激。

谢谢。

【问题讨论】:

    标签: clojure list-comprehension clojurescript


    【解决方案1】:

    您可以使用clojure.string/join 将字符序列转换回字符串。

    您的代码中有几处与原始 Scala 版本略有不同:

    • Scala 版本的范围从 1 开始,你的从 0 开始
    • Scala 版本的 if->true 返回嵌套集合
    • 您将两个序列连接在一起,而不是“consing”到列表中

    我创建了一个可能不完全正确的修改版本(没有根据 Scala 版本的输出检查它),但希望对您有所帮助:

    (defn encode
      "Takes a number as a string. Returns all the different ways to encode that number as a list of words"
      [number]
      (if (empty? number)
        #{()}
        (for [split (range 1 (inc (count number)))
              word  (words-from-number (join (take split number)))
              remainder (encode (join (drop split number)))] 
          (cons word remainder))))
    

    可能感兴趣的是我不久前实现了相同的翻译:https://gist.github.com/ponzao/6095989

    【讨论】:

    • 我最初确实使用了 clojure.string/join,但它只是 感觉 错误 join/split/join/split... Scala 的字符串似乎表现得很好作为序列,因此使用take 和join 返回一个字符串,但在clojure 中它们返回一个字符列表,所以我觉得使用subs 会更合适。最后,您的修改版本与我最初的尝试(不是发布的版本)相同,在所有 tweeking 之前,重要的区别是当字符串用完时您返回一个空集。公平地说,这就是 Scala 版本所做的。
    猜你喜欢
    • 2020-06-03
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    相关资源
    最近更新 更多