1

listと number(element-at x k)の 2 つのパラメーターを持つという関数を作成しました。リストの K 番目の要素を返します。xk

たとえば、式は を(element-at '(a b c d) 3)返しますc。次に、 listと number(remove-at x y)の 2 つのパラメーターを持つ関数が呼び出されます。リストから K 番目の要素を削除します。たとえば、式は を返します。xk(remove-at '(a b c d) 3)(a b d)

(remove-at x y)I used the function (element-at x k)but the function will not workの定義で(remove-at x y)、Dr.racket から「Program run out of memory」と表示されました。だれか理由を知り、できるだけ早く修正できますか?

(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代入firstに使用するのremove-atですか? tail渡された完全なリストに割り当てるのはなぜですか? 書かれているように、メモリエラーが発生していなくても、(remove-at '(a b c d e f c d) 7)どの要素を削除するかを決定する方法を考慮して、何が返されるかを考えてください。

前述のように、 を行っている(append (remove-at x y) (cdr tail))ため、リストと番号が実際に小さくなることはありません。結果に近づかない再帰を書きました。結果として、remove-atは永久に回転し、それ自体にappendingされます(たまたま最初に にならない限り)。xcdr(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) を入力すると、期待どおりに「false」ではなくエラーが発生します。より簡単な実装を次に示します。

(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) false を返します。(remove-at2 (list 'a 'b 'c 'd) 3) '(abd) を返す

于 2012-05-28T17:54:33.717 に答える