gpt4 book ai didi

list - 避免使用集合!进入函数式编程风格算法

转载 作者:行者123 更新时间:2023-12-05 00:11:23 25 4
gpt4 key购买 nike

我不确定我是否可以在这里问这个问题。如果这不是正确的地方,请告诉我,我将删除它。

我正在学习 Racket,有人告诉我一些关于避免使用 set! 的事情以函数式编程风格。但是我很困惑,我不明白“函数式编程风格”的含义。只是为了学习,我想问这个问题。

我有以下代码:

 (define lst1 '())

(do ([i n (- i 1)])
((zero? i))
; Get an item.
(set! item (random-chooser original-list))
; Insert it into an auxiliary list, lst1
(set! lst1 (cons item lst1))
; Remove the item from the original list
(set! original-list (remove item original-list)))

(append (list lst1) (list original-list))))))

这段代码运行良好。我必须选择 n来自 original-list 的项目随机列出,不重复。然后使用 n 创建一个包含两个子列表的列表 lst1 中选择的项目作为第二个子列表, original-list 上的剩余项目.

有没有更好的方法来做到这一点而不使用 set! ?

最佳答案

为了删除使用set!和显式循环,您需要使用递归,将“更新”值作为参数传入。

Scheme 在 letrec 周围有一些很好的语法糖。 (递归 let ,用于可以引用自身的绑定(bind)),它允许您一次性创建和调用函数:named let .这常用于循环,所以函数常被称为loop ,但它可以被称为其他任何东西。重要的是在循环时用修改后的参数调用它,而不是在循环结束时调用它。

(define (take-random n lst)
; Syntactic sugar that creates a 3-parameter function called `loop` and calls it
; with the values `n`, `'()` and `lst`
(let loop ((n n)
(picked '())
(lst lst))
; If the loop counter reaches zero or if there are no more items to take
(if (or (zero? n) (null? lst))
; Then combine the picked items and the remaining unpicked items
(list picked lst)
; Otherwise, pick a random item from the list
(let ((item (random-chooser lst)))
; And loop again, decreasing the loop counter to be nearer zero,
; adding the picked item to the list of picked items, and removing
; it from the list of remaining items to pick from
(loop (- n 1)
(cons item picked)
(remove item lst))))))

;; Examples
(take-random 3 '(1 2 3 4 5 6))
; => ((4 1 6) (2 3 5))
(take-random 3 '(1 2))
; => ((2 1) ())

Óscar López's answer很好地展示了执行此操作的更实用的方式。

关于list - 避免使用集合!进入函数式编程风格算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53609521/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com