封装列表的某些部分

时间:2013-04-09 06:01:08

标签: scheme

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

(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(右侧折叠操作),我更倾向于它就此而言。

3 个答案:

答案 0 :(得分: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 :(得分:0)

只是为了好玩,这是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)))]))))

答案 2 :(得分:0)

这是另一种方法,也没有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))]))))