如何使用scheme删除列表中的最后一个元素

时间:2016-11-15 17:30:47

标签: recursion scheme

我需要使用递归过程返回列表中的最后一个负数。现在我有一个递归过程,返回列表中的所有负数。

(define returnLastNeg
  (lambda (lst) 
    (if (null? lst) 
        '() 
        (if (positive? (car lst)) 
            (returnLastNeg (cdr lst))
            (cons (car lst) (returnLastNeg (cdr lst)))))))

使用(returnLastNeg'(1 -2 -3 4 -5 6))调用

输出:

'(-2 -3 -5)

我需要它只返回-5。我试图修改我的程序以检查列表中的最后一个元素是否为正。如果是,我想删除最后一个元素,然后再次调用该过程。但是当我这样做时,我得到一个错误(下面)

修改程序:

(define returnLastNeg-modified
  (lambda (lst) 
    (if (null? lst) 
        '() 
        (if (positive? (last lst))
            (remove (last lst) (lst))
            (cons (car lst) (returnLastNeg-modified (cdr lst)))))))

错误:

application: not a procedure;
 expected a procedure that can be applied to arguments
  given: '(1 -2 -3 4 -5 6)
  arguments...: [none]
> 

1 个答案:

答案 0 :(得分:0)

在这个例子中,一个更简单的方法是使用辅助程序(称为" sub"):

 
(define returnLastNeg
  (lambda (lst)
    (define sub
      (lambda (lst last-neg)
        (if (null? lst)
            last-neg
            (let ((c (car lst)))
              (sub (cdr lst)
                   (if (negative? c) c last-neg))))))  
    (sub lst null)))

修改

知道

(define <procedureName> (lambda (<params>) ... )

相同
(define (<procedureName> <params>) ... )

并重新格式化,这变为:

(define (returnLastNeg lst)

  (define (sub lst last-neg)
    (if (null? lst)
        last-neg
        (let ((c (car lst)))
          (sub (cdr lst) (if (negative? c) c last-neg)))))

  (sub lst null))

我希望它更清楚

  • last-neg被最后一个表达式
  • 设置为null
  • sub的递归调用有2个参数(在初始版本中分为2行,但换行不重要。)

这与更短的版本相同

(define (returnLastNeg lst)
  (let sub ((lst lst) (last-neg null))
    (if (null? lst)
        last-neg
        (let ((c (car lst)))
          (sub (cdr lst) (if (negative? c) c last-neg))))))

使用所谓的&#34;命名为let&#34;。