重写列表列表中的项目
Rewrite an item in a list of list
这看起来很简单,但我似乎找不到解决方案。我想用某些东西替换列表列表中的一个项目, 但是 如果该项目出现多次,那么你随机替换其中一个,但不能同时替换两个。我想在 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) 可能 return 这个或任何其他 '- 所在的位置:
(list
(list 2 2 2 2)
(list 4 '- 4 2)
(list '- 8 8 8)
(list 16 '- '- 16))
我已经研究了一段时间,所以任何新的见解都会有很长的路要走。谢谢
如何用另一个值替换所有出现的值:
(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?
比较结构。
它不是随机的。它将通过在 cdr
之前执行 car
或在 car
.
之前执行 cdr
来替换它找到的第一次出现
"random" 部分是导致此问题病态的原因。如果您可以只替换 first 的出现,那将很容易。但是要替换一个 random 的出现,你必须首先知道有多少次出现。所以在你去更换东西之前,你必须去数数:
(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)
这看起来很简单,但我似乎找不到解决方案。我想用某些东西替换列表列表中的一个项目, 但是 如果该项目出现多次,那么你随机替换其中一个,但不能同时替换两个。我想在 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) 可能 return 这个或任何其他 '- 所在的位置:
(list
(list 2 2 2 2)
(list 4 '- 4 2)
(list '- 8 8 8)
(list 16 '- '- 16))
我已经研究了一段时间,所以任何新的见解都会有很长的路要走。谢谢
如何用另一个值替换所有出现的值:
(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?
比较结构。
它不是随机的。它将通过在 cdr
之前执行 car
或在 car
.
cdr
来替换它找到的第一次出现
"random" 部分是导致此问题病态的原因。如果您可以只替换 first 的出现,那将很容易。但是要替换一个 random 的出现,你必须首先知道有多少次出现。所以在你去更换东西之前,你必须去数数:
(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)