在方案中生成 2-列表的列表
(define cart-product
(lambda (sos1 sos2)
(if (null? sos1) '()
(cons
(cart-prod-sexpr (car sos1) sos2)
(cart-product (cdr sos1) sos2)))))
(define cart-prod-sexpr
(lambda (s sos)
(if (null? sos) '()
(cons
(list s (car sos))
(cart-prod-sexpr s (cdr sos))))))
调用 (cart-product '(qw) '(xy))
会生成 (((qx) (qy)) ((wx) (wy)))
。
我如何生成 ((qx) (qy) (wx) (wy))
呢?
(define cart-product
(lambda (sos1 sos2)
(if (null? sos1) '()
(cons
(cart-prod-sexpr (car sos1) sos2)
(cart-product (cdr sos1) sos2)))))
(define cart-prod-sexpr
(lambda (s sos)
(if (null? sos) '()
(cons
(list s (car sos))
(cart-prod-sexpr s (cdr sos))))))
Calling (cart-product '(q w) '(x y))
produces (((q x) (q y)) ((w x) (w y)))
.
How I can produce ((q x) (q y) (w x) (w y))
instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
高阶函数获胜。 Haskell 的列表推导转换为 Scheme 以获得更好的解决方案:
它以 m*n (m = |xs|, n = |ys|) 运行。 concatenate 来自 SRFI-1。
Higher order functions for the win. Haskell's list comprehesion translated to Scheme for a nicer solution:
It runs in m*n (m = |xs|, n = |ys|). concatenate is from SRFI-1.
未经测试。请注意,我定义的
append-list
过程实际上返回一个以sos2
结尾的列表。这在这里是适当的(也是正确的做法),但并不普遍。请注意,如果列表的大小为 n,则需要时间 O(n3) 才能生成大小为 O(n2) 的列表。
使用常规我刚刚实现了常规append
会花费 O(n4)。append
而没有实现它。如果你想获得 O(n2),你必须更加聪明。就像这段未经测试的代码一样。如果我遇到错误,想法是递归循环第一个和第二个元素的所有组合,每个组合都将
answer-current
替换为cons
,又一个组合,然后是我们已经找到的其他所有组合。由于尾部调用优化,这应该是高效的。Untested. Note that the
append-list
procedure I defined actually returns a list ending insos2
. That is appropriate (and the right thing to do) here, but is not in general.Note that if the lists are of size n then this will take time O(n3) to produce a list of size O(n2).
Using regularI just implemented the regularappend
would take O(n4) instead.append
without realizing it. If you want to take O(n2) you have to be more clever. As in this untested code.In case I have a bug, the idea is to recursively loop through all combinations of elements in the first and the second, with each one replacing
answer-current
with acons
with one more combination, followed by everything else we have found already. Thanks to tail-call optimization, this should be efficient.从我的头顶上掉下来:
Off the top of my head:
=>
((1 A) (1 B) (1 C) (2 A) (2 B) (2 C) (3 A) (3 B) (3 C))
[注:解为对于Common Lisp(CLisp)而不是Scheme,但我认为它在Scheme中应该非常相似]
外部(reduce #'append)用于替换(concatenate(map),如knivil在解决方案中给出的
但是,我不确定如何与其他解决方案相比,我的解决方案在性能参数上有所提高,有人可以对此发表评论吗?
=>
((1 A) (1 B) (1 C) (2 A) (2 B) (2 C) (3 A) (3 B) (3 C))
[Note: Solution is for Common Lisp (CLisp) and not Scheme, but I suppose it should be very similar in Scheme]
The outer (reduce #'append ) is for replacing (concatenate (map ) as given in solution by knivil
However, I am not sure how my solution stacks up on performance parameters compared to other solutions. Can somebody please comment on that?
这只是同一问题的不同解决方案。我认为这很容易理解,也许会对某人有所帮助。
Here is just different solution on the same problem. I think that this is easy for understanding and maybe will be helpful for someone.