【问题标题】:Encapsulating Certain Parts of List封装列表的某些部分
【发布时间】:2013-04-09 06:01:08
【问题描述】:

我正在尝试编写一个在“分隔符”元素之间“封装”(即放入列表中)列表元素的过程。

(my-proc '(1 + 2))
=> ((1) (2))

(my-proc '(x * y + z ^ 2 + 1 + 5))
=> ((x * y) (z ^ 2) (1) (5))

(my-proc '((x + 1) * y + 5))
=> (((x + 1) * y) (5))

在这种情况下,可以对过程进行硬编码以将 + 符号定义为分隔符。

假设定义了 foldr(右折叠操作),我更喜欢它。

【问题讨论】:

    标签: scheme


    【解决方案1】:

    我没有给出完整的解决方案,因为这看起来真的很家庭作业。

    (define (split-expr expr)
       (foldr (lambda (e es)
                      (if (eq? e '+)
                          <???>    ; do split
                          (cons (cons e (car es))
                                (cdr es))))
              <???>    ; what should start be?
              es))
    

    【讨论】:

    • +1 表示正确的方法,但我将编辑您的答案以添加 &lt;???&gt; 以指示要填写的内容。 cmets 本身(没有占位符)确实令人困惑。 (当然,我实际上自己实现了完整的解决方案。)
    • 我很困惑。 start 显然不能是 '(),因为该操作调用 (car es) 和 (cdr es),但我没有看到它可能是什么。即使那样,我也不知道 if 语句的替代子句应该完成什么,例如,给定 e 是 1 并且 es 是 (2 3),结果将是 ((1 . 2) 3)。请您提供更多提示吗?
    • 好吧,这不可能是'(),你是对的,但是'( () )
    • 谢谢,我知道了。但是该死的,就在我以为我已经习惯了 Scheme 的时候,即使是这么简单的事情,我也没有帮助。
    【解决方案2】:

    只是为了好玩,这是continuation-passing style 中的一个版本(不是foldr,可能不适合作为家庭作业答案):

    (define split/cps
      (λ (sep ls)
        (let loop ([ls ls] [k (λ (item acc)
                                   (if item (cons item acc) acc))])
          (cond
            [(null? ls)
              (k #f '())]
            [(eq? sep (car ls))
              (loop (cdr ls)
                    (λ (item acc)
                      (k #f (if item (cons item acc) acc))))]
            [else
              (loop (cdr ls)
                    (λ (item acc)
                      (k (if item
                             (cons (car ls) item)
                             (list (car ls)))
                         acc)))]))))
    

    【讨论】:

      【解决方案3】:

      这是另一种方法,同样没有foldr

      (define split/values
        (λ (sep ls)
          (let loop ([ls ls])
            (cond
              [(null? ls)
                '()]
              [else
                (let-values ([(a d) (car-to-sep sep ls)])
                  (if (null? a)
                      (loop d)
                      (cons a (loop d))))]))))
      
      (define car-to-sep
        (λ (sep ls)
          (let loop ([ls ls] [a '()])
            (cond
              [(null? ls)
                (values '() '())]
              [(eq? sep (car ls))
                (values '() (cdr ls))]
              [else
                (let-values ([(a d) (loop (cdr ls) a)])
                  (values (cons (car ls) a) d))]))))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-25
        • 1970-01-01
        • 2018-07-27
        • 1970-01-01
        相关资源
        最近更新 更多