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过于复杂,而且相互递归也不是你想的那样。如果我们简化这些过程并确保只对输入列表执行一次传递,我们可以获得正确的答案:

(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 回答