我知道如何使用列表推导来做到这一点,但是我如何实现一个递归计算给定两组笛卡尔积的函数?
这就是我被困住的地方(我是一个菜鸟)
crossProd :: [Int] -> [Int] -> [(Int,Int)]
crossProd xs ys | xs == [] || ys == [] = []
| otherwise = (head xs, head ys) : crossProd (tail xs) (ys)
这个输出给了我
[(1,4),(1,5),(1,6)]
如果这些集合分别为[1,2,3]
和[4,5,6]
。
我怎么去休息呢?
答案 0 :(得分:4)
最基本的情况是:
{-crossProdAux :: Int -> [Int] -> [(Int,Int)]-}
crossProdAux x [] = []
crossProdAux x (a:b) = (x, a):(crossProdAux x b)
{-crossProd :: [Int] -> [Int] -> [(Int,Int)]-}
crossProd [] ys = []
crossProd (a:b) ys= (crossProdAux a ys)++(crossProd b ys)
答案 1 :(得分:3)
这可以在一个功能中完成:
crossProd :: [a] -> [b] -> [(a, b)]
crossProd (x:xs) ys = map (\y -> (x, y)) ys ++ crossProd xs ys
crossProd _ _ = []
请注意,我已对您的类型进行了一般化,以便适用于任何a
和b
,而不仅仅是Int
。
这个函数的关键是要理解你想要将第一个列表中的每个元素与第二个列表中的每个元素配对。因此,此解决方案从第一个列表中获取一个元素x
,并将其与ys
中的每个元素配对。这是通过映射一个函数来完成的,该函数从y
获取每个值ys
,并将其转换为一对(x, y)
。我们将其添加到与列表xs
的其余部分一起递归的前面。
在基本情况下,没有任何东西可以配对,因此输出为空。