这似乎很简单,但我似乎无法找到解决方案。我想用列表替换列表列表中的项目,但如果该项目多次出现,则随机替换其中一项,但不能同时替换两者。我想在ISL +中这样做。
我创建了flatten函数,它附加了所有子列表:
(check-expect (flatten '((a b) (c) (d e f g) (h i j)))
(list 'a 'b 'c 'd 'e 'f 'g 'h 'i 'j))
(define (flatten lol)
(foldr append empty lol))
我也做了重写,用你选择的任何东西替换索引n的值
(check-expect (rewrite '(x x x - x x x x) 3 'x)
(list 'x 'x 'x 'x 'x 'x 'x 'x))
(define (rewrite ls n val)
(cond
[(empty? ls) (error "error")]
[(= n 0) (cons val (rest ls))]
[else (cons (first ls) (rewrite (rest ls) (sub1 n) val))]))
问题是我不知道如何将其应用到列表列表中,如果多次出现,我也不知道如何随机替换其中一个项目。这就是我对最终产品所拥有的,但它可能不是最佳选择:
(define (fullreplace b)
(local [
;makes a list of nested lists of each index the element occurs
;problem is that it makes a list of nested lists so I can't use flatten either
(define (position ls ele n)
(cond [(empty? ls) 0]
[(equal? ele (first ls)) (list n (position (rest ls) ele (add1 n))) ]
[else (position (rest ls) ele (+ 1 n))]))]
;lol-full? checks if the item occurs in the list of lists at all
(if (lol-full? b) b (rewrite (flatten b)
(position (flatten b) '- 0)
"item replaced"))))
;just used for testing
(define lol2 (list
(list 2 2 2 2)
(list 4 '- 4 '-)
(list '- 8 8 8)
(list 16 '- '- 16)))
(fullreplace lol2)可能会返回此内容或其他任何位置:
(list
(list 2 2 2 2)
(list 4 '- 4 2)
(list '- 8 8 8)
(list 16 '- '- 16))
我一直在努力工作,所以任何新的见解都会有很长的路要走。谢谢
答案 0 :(得分:2)
"随机"部分是使这个问题病态的原因。如果您只是替换第一个事件,那将很容易。但要替换随机出现,您必须首先知道有多少次出现。因此,在你更换东西之前,你必须进行计算:
(define (count/recursive val tree)
(cond ((equal? val tree)
1)
(else (foldl (λ (next-value total)
(cond ((equal? val next-value)
(add1 total))
((list? next-value)
(+ total (count/recursive val next-value)))
(else total))) 0 tree))))
然后你需要一个可以替换第n次出现的函数:
(define (replace/recursive val replace-with n tree)
(cond ((equal? val tree)
replace-with)
(else
(cdr
(foldl (λ (next-value total/output-tree)
(local ((define total (car total/output-tree))
(define output-tree (cdr total/output-tree)))
(cond ((equal? next-value val)
(cons (add1 total)
(cons (if (= total n) replace-with next-value) output-tree)))
((list? next-value)
(cons (+ total (count/recursive val next-value))
(cons (replace/recursive val replace-with (- n total) next-value)
output-tree)))
(else (cons total (cons next-value output-tree)))))) (cons 0 empty) tree)))))
最后,您使用random
选择要替换的实例,使用count/recursive
来限制random
次选择的数量:
(define original '((x x (x y x) a b (((c x z x) x) y x x))))
(replace/recursive 'x '- (random (count/recursive 'x original)) original)
答案 1 :(得分:1)
如何用另一个值替换值的所有出现:
(define (replace-all needle new-value haystack)
(cond ((equal? needle haystack) new-value)
((pair? haystack)
(cons (replace-all needle new-value (car haystack))
(replace-all needle new-value (cdr haystack))))
(else haystack)))
唯一要改变的是检查第一部分是否构成变化。如果它确实你没有在另一半做替换。使用equal?
来比较结构。
不随机。它会在car
前cdr
或cdr
之前car
替换它找到的第一个出现。