我希望在对中替换第一次出现的符号。例如: 采取
(define n '((a . b) . (a . d)))
我定义了一个方法上下文来替换X的第一个实例(最左边)和'() 替换a应该给我:
((() . b) a . d)
但是我被卡住了,因为我的方法替换了所有实例,我不知道如何为此添加检查。 我的代码如下:
(define (context s sym)
(cond ((null? s) #f)
((atom? s)
(if (equal? s sym) '() s ))
(else (cons (context (car s) sym)
(context (cdr s) sym)))))
给出:((()。b)()。d)
任何帮助?谢谢
答案 0 :(得分:0)
最快捷的方法是使用一个标志,指示替换是否已经完成,具体如下:
(define (context sxp sym)
(define done #f)
(let loop ((sxp sxp))
(cond (done sxp)
((pair? sxp) (cons (loop (car sxp)) (loop (cdr sxp))))
((eq? sym sxp) (set! done #t) '())
(else sxp))))
使用set!
并不是很优雅,但替代方法是让过程返回2个值,并且生成的let-values
代码在可读性方面会更糟糕IMO
另请注意,我没有使用atom?
,因为它没有在标准方案中定义;通常的方法是先后测试null?
然后pair?
,并处理else
子句中的原子大小写。
答案 1 :(得分:0)
这是更通用的(您可以替换除符号之外的其他内容,并且您可以自定义测试,并且您可以指定要替换的任何特定数量的实例,而不仅仅是一个),并且可能稍微复杂一些乍一看比你正在寻找的,但这里是一个解决方案,通过内部使用延续传递样式辅助函数。主要功能 subst-n 采用 new 元素,旧元素,树,测试和计数。它将 new 的第一个 count 次出现(与 test 相比)替换为 old (或全部,如果< em> count 不是非负整数。)
(define (subst-n new old tree test count)
(let substs ((tree tree)
(count count)
(k (lambda (tree count) tree)))
(cond
;; If count is a number and zero, we've replaced enough
;; and can just "return" this tree unchanged.
((and (number? count) (zero? count))
(k tree count))
;; If the tree is the old element, then "return" the new
;; element, with a decremented count (if count is a number).
((test old tree)
(k new (if (number? count) (- count 1) count)))
;; If tree is a pair, then recurse on the left side,
;; with a continuation that will recurse on the right
;; side, and then put the sides together.
((pair? tree)
(substs (car tree) count
(lambda (left count)
(substs (cdr tree) count
(lambda (right count)
(k (cons left right) count))))))
;; Otherwise, there's nothing to do but return this
;; tree with the unchanged count.
(else
(k tree count)))))
> (display (subst-n '() 'a '((a . b) . (a . d)) eq? 1))
((() . b) a . d)
> (display (subst-n '() 'a '((a . b) . (a . d)) eq? 2))
((() . b) () . d)