1

このコードは、一人称の単語を二人称の単語に、またはその逆に置き換えます。ただし、フレーズ内の各単語の各ペアを通過するため、元に戻る場合があります。

コードは次のとおりです。

(define (replace pattern replacement lst replacement-pairs)
  (cond ((null? lst) '())
    ((equal? (car lst) pattern)
       (cons replacement
             (many-replace (cdr replacement-pairs) (cdr lst))))
    (else (cons (car lst)
          (many-replace (cdr replacement-pairs) (cdr lst))))))

(define (many-replace replacement-pairs lst)
  (cond ((null? replacement-pairs) lst)
     (else (let ((pat-rep (car replacement-pairs)))
        (replace (car pat-rep)
                 (cadr pat-rep)
                 (many-replace (cdr replacement-pairs)
                 lst) replacement-pairs)))))

(define (change-person phrase)
  (many-replace '((i you) (me you) (am are) (my your) (are am) (you i) (your my))
            phrase))

たとえば、私が入力した場合

(change-person '(you are not being very helpful to me))

それはあなたを私に変えますが、それからあなたに戻ります。これを修正するにはどうすればよいですか?

4

2 に答える 2

3

手順replacemany-replaceは非常に複雑であり、相互再帰はあなたが思っていることをしていません。これらの手順を簡略化し、入力リストに対して1回のパスのみが実行されるようにすると、正しい答えを得ることができます。

(define (replace replacement-pairs pattern)
  (cond ((null? replacement-pairs)
         pattern)
        ((equal? (caar replacement-pairs) pattern)
         (cadar replacement-pairs))
        (else
         (replace (cdr replacement-pairs) pattern))))

(define (many-replace replacement-pairs lst)
  (if (null? lst)
      '()
      (cons (replace replacement-pairs (car lst))
            (many-replace replacement-pairs (cdr lst)))))

鋭い目は、以前の手順がいくつかの高次の手順を使用することによって簡潔な方法で表現できることに気付くでしょう。より慣用的な解決策は次のようになります。

(define (replace replacement-pairs pattern)
  (cond ((assoc pattern replacement-pairs) => cadr)
        (else pattern)))

(define (many-replace replacement-pairs lst)
  (map (curry replace replacement-pairs) lst))

いずれにせよ、期待どおりに機能します。

(change-person '(you are not being very helpful to me))
=> '(i am not being very helpful to you)
于 2013-02-26T19:16:49.390 に答える
0

私は少し簡単な解決策を書きました:

(define (many-replace pattern phrase)
  (let loop ((phrase phrase) (result '()))
    (if (empty? phrase) (reverse result)
        (let* ((c (car phrase)) (a (assoc c pattern)))
          (if a
              (loop (cdr phrase) (cons (cadr a) result))
              (loop (cdr phrase) (cons c result)))))))

(change-person '(you are not being very helpful to me))
=> '(i am not being very helpful to you)
于 2013-02-26T19:16:29.683 に答える