Functional programming Racket中3个列表的函数编程
我可以管理以下代码,用另外两个列表替换列表中的项目。Orilist和newlist按顺序具有原始术语和新术语。使用orilist和newlist进行替换-如果orilist项存在于slist中,则slist将更改为具有来自newlist的相应新项:Functional programming Racket中3个列表的函数编程,functional-programming,scheme,racket,Functional Programming,Scheme,Racket,我可以管理以下代码,用另外两个列表替换列表中的项目。Orilist和newlist按顺序具有原始术语和新术语。使用orilist和newlist进行替换-如果orilist项存在于slist中,则slist将更改为具有来自newlist的相应新项: (define (list-replace-from-lists slist orilist newlist) (define replaced #f) (define outl '()) (for ((item slist))
(define (list-replace-from-lists slist orilist newlist)
(define replaced #f)
(define outl '())
(for ((item slist))
(set! replaced #f)
(for ((ori_ orilist) (i (in-naturals)) #:when (equal? item ori_))
(set! outl (cons (list-ref newlist i) outl))
(set! replaced #t))
(when (not replaced)
(set! outl (cons item outl))))
(reverse outl))
将列表1 2 3 4 5 6中的2和5分别替换为12和15:
(list-replace-from-lists (list 1 2 3 4 5 6) (list 2 5) (list 12 15))
输出为:
'(1 12 3 4 15 6)
然而,上面的代码看起来并没有功能,并且有很多设置!声明。如何将其转换为功能代码?出于上述目的,我应该使用结构或其他数据类型吗
编辑:项目可能会在原始列表中重复出现,例如列表1 2 3 4 5 2 6您仍然可以使用列表并保持一切功能正常:以下是我的解决方案:
(define (replace-all haystack needles new-needles)
(define replace-alist (map cons needles new-needles))
(define (replace-one item)
(cond ((assoc item replace-alist) => cdr)
(else item)))
(map replace-one haystack))
守则解释:
首先,我们构建一个替换关联列表。这是对的列表,其中键对应于针,值对应于新针
然后我们定义一个replace one函数,它接受一个项,并查看它是否匹配列表中的任何键。如果是,我们返回相应的值;否则,我们将返回原始项目
最后,我们通过替换一来映射干草堆。是的,高阶函数
注意,这段代码是Om*n,其中m是草堆的大小,n是针的大小,与您的版本运行时相同。如果指针较大,您将希望使用哈希表而不是列表,这将把函数的运行时分摊到Om。这是一个使用哈希来保持关联的函数解决方案。这使得该解决方案具有堆栈长度对数针长度,因为不可变哈希是用树实现的
(define (list-replace-all haystack needles new-values)
;; make a dictionary of elements to be replaced
(define hash
(foldl (λ (needle new-value hash)
(hash-set hash needle new-value))
#hash()
needles
new-values))
;; do the replace. If not in hash the actual key is default
(map (λ (e) (hash-ref hash e e)) haystack))
(list-replace-all '(1 2 3 4 5 6) '(2 5) '(12 15))
; ==> (1 12 3 4 15 6)
如果项目稍后在haystack中再次出现,例如替换列表1 2 3 4 5 2 6列表2 5列表12 15,则您的解决方案不起作用。第二个2没有被替换。我发布了一个简单的示例,您的解决方案在这方面非常优雅。但不排除重复项目。完美。感谢您的解答以及清晰的解释。如果为了清晰起见,您可以将哈希表版本放在这里,这对所有读者都是非常好的。您能在这里解释一下=>的用法吗。这似乎是一个不常用的符号。@rnso Sylvester已经发布了一个哈希版本,所以我不想麻烦这么做了。.-至于=>,它是存储测试值的cond语法,如果是truthy,则将其传递给给定函数。在这种情况下,它相当于:如果值cdr value。。。在哪里。。。表示失败情况。首选使用for/hash作为此for/hash针在列表中针在列表中的新值新值针新值。否则,答案很好+我很高兴我的问题给出了有教育意义的答案。我不知道为什么这个问题被否决了。@ChrisJester Young是的,它看起来更清楚。为什么在列表中使用?两者都已经是一个列表,每个元素都将被触及@mso可能是因为它有效。“这更多的是一个问题,”西尔维斯特说,“这是一个微观优化。在不指定生成器的情况下,系统必须在运行时查看对象的类型以决定要使用的生成器。。列表mylist中项目的vs。在列表中,第二个版本要快得多。类似地,对于范围n中的i,速度比对于范围n中的i或i快得多。