0

特定のパターンを見つけて置き換えるスキームプログラムを作成する必要があり、ネストの1つのレイヤーのみで動作するようにしましたが、リストの次の車がリスト自体である場合、プログラムは適切に再帰しません.

これが私がこれまでに持っているものです:

(define replace 
    (lambda (source target replacement) 
        (if (eqv? source target)
            replacement
            (if (null? source)
                '() ;;base case

                (if (equal? target (car source))
                    (cons replacement (replace (cdr source) target replacement))

                    (cons (car source)
                    (replace (cdr source) target replacement))
                )
            )
        )
    )
)
4

3 に答える 3

1

に置き換える必要がeqv?ありequal?ます。を使用eqv?すると、次のように期待する結果が得られません。

> (eqv? (list 1 2 3) (list 1 2 3))
#f
> (eqv? '(1 2) '(1 2))
#f ; some Schemes may return #t

コードに関しては、一連のcond句としてより読みやすくコンパクトに記述されています。

(define (replace source target replacement) 
  (cond ((eqv? source target) replacement)
        ((null? source)      '()) ;;base case
        ((equal? target (car source))
         (cons replacement (replace (cdr source) target replacement)))
        ((not (list? (car source)))
         (cons (car source) (replace (cdr source) target replacement)))
        (else
         (cons (replace (car source) target replacement) 
               (replace (cdr source) target replacement)))))

また、アルゴリズムをより明確に説明する別のアプローチ (「handle carand cons it to handing of cdr」) は次のとおりです。

(define (replace source target replacement)
  (cond ((null? source)'())
        ((equal? source target) replacement)
        (else (let ((next (car source))
                    (rest (cdr source)))
                (cons (if (not (list? next))
                          next
                          (replace next target replacement))
                      (replace rest target replacement)))))
于 2013-09-23T00:13:45.153 に答える
0

あなたのエラーは、それcarが一致しておらず、アトムではない場合に置換を行わないことです。すべてのペアを追跡できるようにすることで、これを非常にコンパクトに書くことができます。

(define (replace source target replacement) 
  (cond ((equal? source target) replacement) ;; equal, return replacement
        ((not (pair? source)) source)        ;; not equal && not pair, return source
        (else (cons (replace (car source) target replacement) ;; recurse
                    (replace (cdr source) target replacement)))))
于 2013-09-23T18:47:10.397 に答える
0

私の最初のバージョンでは、(car source) がリストであるかどうかを確認していなかったため、別の条件を追加することを避けるために、個別のトークンとして扱われていました。

(define replace 
    (lambda (source target replacement) 
        (if (eqv? source target)
            replacement
            (if (null? source)
                '() ;;base case

                (if (equal? target (car source))
                    (cons replacement (replace (cdr source) target replacement))

                    (if (not (list? (car source)))
                        (cons (car source) (replace (cdr source) target replacement))
                        (cons (replace (car source) target replacement) (replace (cdr source) target replacement))))))))
于 2013-09-22T23:38:01.200 に答える