这个功能给我“程序内存耗尽”?

时间:2012-05-26 23:22:49

标签: scheme racket

我写了一个名为(element-at x k)的函数,它有两个参数:列表x和数字k。它返回列表的第K个元素。

例如,表达式(element-at '(a b c d) 3)返回c。 然后是一个名为(remove-at x y)的函数,它有两个参数:列表x和数字k。它从列表中删除了K'th元素。例如,表达式(remove-at '(a b c d) 3)返回(a b d)

(remove-at x y)的定义中,我使用了函数(element-at x k),但函数(remove-at x y)不起作用,Dr.racket给了我“程序内存不足”,可以任何一个知道为什么并尽快解决它?

(define (element-at lis k) (if (null? lis) (if (> k 0) #f '()) (let ((head (car lis)) (tail (cdr lis))) (if (< k 2) head (element-at tail (- k 1))))))

(define (remove-at x y) (let ((first (element-at x y)) (tail x)) (if (equal? (car x) first) (append (remove-at x y) (cdr tail)) (cdr tail))))

2 个答案:

答案 0 :(得分:1)

首先,如果安排得当,您的代码会显示

(define (element-at lis k)
  (if (null? lis)
      (if (> k 0) #f '())
      (let ((head (car lis))
            (tail (cdr lis)))
        (if (< k 2)
            head
            (element-at tail (- k 1))))))

(define (remove-at x y)
  (let ((first (element-at x y))
        (tail x))
    (if (equal? (car x) first)
        (append (remove-at x y) (cdr tail))
        (cdr tail))))

为什么使用element-atfirst中分配remove-at?为什么要将tail分配给传入的完整列表?如上所述,即使它没有给你一个内存错误,考虑一下(remove-at '(a b c d e f c d) 7)会返回什么,考虑你如何决定删除哪个元素。

如前所述,由于您正在执行(append (remove-at x y) (cdr tail)),因此您的列表和号码实际上从未变小。您已经编写了一个不会接近结果的递归。因此,remove-at将永远旋转,append x cdr自己的(car x)(除非equal?恰好是(element-at x y)到{{1}})。

我认为这是一项家庭作业,所以我只是指出了你的错误并将它们作为一种练习。如果情况并非如此,请告诉我们,我们可以查看工作版本。

答案 1 :(得分:0)

这有效

(define (element-at lis k) 
   ( if(null? lis)
       (if(> k 0) #f '()) 
       ( let( (head (car lis))(tail (cdr lis)) ) 
       (if(< k 2) head (element-at tail (- k 1 )))) ) )

(define (remove-at x y)
   (let ((first (element-at x y))
        (tail x))
    (if (equal? (car x) first)
        (cdr tail)
        (cons (car x) (remove-at (cdr tail) (- y 1))))))

(remove-at(列出'a'b'c'd)3)返回'(a b d)。但我可以这么说,这可能是一个非常糟糕的实现这样一个简单的要求。你是故意写它的,以便更深入地了解条件?这是一个不使用辅助功能的简化代码。警告: - 在上面的函数中,如果你输入(remove-at(列出'a'b'c'd)5),它会给出错误而不是预期的“假”。这是一个更简单的实现:

(define (remove-at2 x y)
  (local ((define (remove x y ans-lst)
            (cond ((null? x)
                  (if (> y 0) #f
                      ans-lst))
                  ((= y 1) (append ans-lst (cdr x)))
                  (else
                    (remove (cdr x) (- y 1) (append ans-lst (list (car x))))))))
    (remove x y '())))

(remove-at2(list'a'b'c'd)5)重新表示错误。 (remove-at2(list'a'b'c'd)3)返回'(a b d)