1

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

例如,表达式(element-at '(a b c d) 3)返回c. 然后是一个被调用的函数(remove-at x y),它有两个参数:一个列表x和一个数字k。它从列表中删除第 K 个元素。例如,表达式(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))))
4

2 回答 2

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-at分配firstin 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)

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

于 2012-05-27T02:05:53.237 回答
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 (list 'a 'b 'c 'd) 3) 返回 '(abd)。但我可以说,这可能是一个非常糟糕的实现这样一个简单的要求。是不是为了更深入地理解if条件而特意写成这样的?这是一个没有使用辅助功能的简化代码。警告:- 在上述函数中,如果您输入 (remove-at (list '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) 返回 '(abd)

于 2012-05-28T17:54:33.717 回答