仅当列表中的元素跟随指定元素时,才替换列表中每个元素的出现位置

时间:2016-03-31 14:59:55

标签: recursion functional-programming scheme lisp

我正在尝试编写一个函数replaceAfter(A X Y L),它将每次出现的X替换为L中的Y,只有当X出现在A之后。

示例:

replaceAfter d m t '(f d s d m p m h d m u m) -> '(f d s d t p m h m t u m)

这是我到目前为止所提出的:

(define replaceAfter
    (lambda(A X Y L)
        (cond
            ( (null? L)          '() )
            ( (if (and (equal? (car L) A) (equal? (car (cdr L)) X) ) (cons (cons (car L) Y) (replaceAfter A X Y (cdr (cdr L))))) )
            (#t (cons (car L) (relaceAfter A X Y (cdr L))))
        )
    )
)

3 个答案:

答案 0 :(得分:1)

(define replace-after
  (lambda (d m t lst)
    (let loop ((todo lst)
               (done '())
               (replace #f))
      (if (null? todo)
          (reverse done)
          (let ((item (car todo)))
            (loop (cdr todo)
                  (cons (if (and replace (eq? m item)) t item) done)
                  (eq? item d)))))))

答案 1 :(得分:0)

您应该从第二个分支中删除@Override public void onDowngrade (SQLiteDatabase db, int oldVersion, int newVersion) { // your DB dowgrade code } 。此外,这两个IF es目前正在制作类似CONS而非((1 . 2) . 3)的列表。

(1 . (2 . 3))

答案 2 :(得分:0)

使用执行迭代的子过程最容易实现,在构建结果列表时逐步使用列表l。使用cons代替append不仅可以提高性能,还可以带来积极影响,即结果列表的第一个元素是需要与a进行比较的前一个元素:

(define replace-after
  (lambda (a x y l)
    ; ---- sub procedure  
    (define iter
      (lambda (lst result)
        (if (null? lst)
            (reverse result)
            (let ((current (car lst)))
              (iter (cdr lst)
                    (cons (if (and (not (null? result))    ; there is a previous element
                                   (equal? (car result) a) ; previous is a
                                   (equal? current x))     ; current is x
                              y
                              current)
                          result))))))
    ; call iter
    (iter l '())))

当然,你需要在最后反转结果,但这是继续使用Scheme的规范方法。

如果你添加一点display语句,你会看到它的工作原理:

> (replace-after 'd 'm 't '(f d s d m p m h d m u m))
lst (f d s d m p m h d m u m)  - result ()
lst (d s d m p m h d m u m)  - result (f)
lst (s d m p m h d m u m)  - result (d f)
lst (d m p m h d m u m)  - result (s d f)
lst (m p m h d m u m)  - result (d s d f)
lst (p m h d m u m)  - result (t d s d f)
lst (m h d m u m)  - result (p t d s d f)
lst (h d m u m)  - result (m p t d s d f)
lst (d m u m)  - result (h m p t d s d f)
lst (m u m)  - result (d h m p t d s d f)
lst (u m)  - result (t d h m p t d s d f)
lst (m)  - result (u t d h m p t d s d f)
lst ()  - result (m u t d h m p t d s d f)
'(f d s d t p m h d t u m)

请注意,结果与您在问题中所写的结果不同,但我相信这是正确的。

您的规格中唯一不明确的案例如下:

> (replace-after 'd 'm 'd '(d m m))
lst (d m m)  - result ()
lst (m m)  - result (d)
lst (m)  - result (d d)
lst ()  - result (d d d)
'(d d d)

这应该实际返回'(d d d)还是(d d m)