我希望有人可以指导我朝着正确的方向前进:
我正在寻找两个产生所有可能的项目组合的两个列表:
例如:
鉴于列表'(symbol1 symbol2)和'(1 2),我希望产生:
(列表(列表'symbol1 1)(列表'symbol1 2)(列表'symbol2 1)(列表符号2 2))
到目前为止我的代码是:
(define (combiner list1 list2)
(list
(foldr (lambda (a b) (foldr (lambda (c d) (list a c)) empty list1)) empty list2)
(foldr (lambda (a b) (foldr (lambda (c d) (list b d)) empty list1)) empty list2)))
这显然不起作用,也没有其他一些我尝试过的方法。我在使用两个列表上的隐式递归时遇到了麻烦 - 任何想法?
答案 0 :(得分:4)
您在这里看到的是两个复杂参数的递归,section 17如何设计程序。如果你想要另一个提示,我会告诉你这三种情况中的哪一种。
答案 1 :(得分:1)
我想到了解决问题的另一种可行方法。这是一个提示:
(define (combiner list1 list2)
(define (combine l1 l2)
(cond ((empty? l1) empty)
((empty? l2) XXX)
(else (cons YYY
ZZZ))))
(combine list1 list2))
在上面的代码中,您必须找出三个问题的答案:
XXX
当你完成对第二个列表的迭代时,如何推进递归,但是第一个列表仍然有元素,你还希望在第一个列表中前进一个元素?YYY
您如何将第一个列表中的元素与第二个列表中的元素组合在一起?ZZZ
当两个列表仍然有剩余元素时,如何推进递归,但此时你只对推进第二个列表感兴趣?最后一个提示:请注意,在某些时候你需要“重新启动”第二个列表,为此,你可以参考原来的list2
,它根本没有改变。
我希望这会对你有所帮助,我不想给你一个直接的答案(我) - 我希望你自己找出解决方案。
答案 2 :(得分:0)
似乎有一件事可以增加混淆是list
的自由使用。我将开始使用Haskell表示法来解决您的问题。 ::
表示“有类型”,[Foo]
表示“列表Foo”。
list1 :: [Symbol]
list2 :: [Number]
type Pair = (Symbol, Number)
(combiner list1 list2) :: [Pair]
现在看来你想用foldr
over list2来解决这个问题。
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr需要step :: a -> b -> b
和start :: b
。由于我们希望最终结果为[Pair]
,这意味着b = [Pair]
。那么start
可能是空列表。由于list2填充[a]
广告位,这意味着a = Number
。因此,对于我们的问题,step :: Number -> [Pair] -> [Pair]
combiner :: [Symbol] -> [Number] -> [Pair]
combiner list1 list2 = foldr step start list2
where step :: Number -> [Pair] -> [Pair]
step a b = undefined
start = []
到目前为止,这与您编写的foldr
相同,但我还没有定义step
。那么步功能是什么?从类型来看,我们知道必须使用Number
和[Pair]
并生成[Pair]
。但这些输入意味着什么?那么Number
输入将是list2
的一些元素。 [Pair]
输入将是“到目前为止的结果”。 因此,我们需要使用Number
,然后执行某些内容为其创建Pair
,然后将其打到目前为止的结果上。< / strong>这是我的代码与您的代码开始不同的地方。
step a b = append (doSomething a) b
doSomething :: Number -> [Pair]
doSomething a = undefined
由于您使用Racket,可能会将doSomething
定义为匿名函数,这意味着list1
在范围内。 (因为它在Haskell中的函数的where子句中,所以它在范围内)。您可能会使用该列表来生成组合。
doSomething a = ... a ... list1 ...
实施doSomething
留给读者一个练习,就像转换回Racket一样。请注意,我在此处定义的Haskell函数的类型签名combiner
可以推广到[a] -> [b] -> [(a,b)]
。