【问题标题】:Cartesian product two lists [duplicate]笛卡尔积两个列表[重复]
【发布时间】:2012-02-09 15:31:05
【问题描述】:

可能重复:
F# - cross product of two lists
Projecting a list of lists efficiently in F#

我有一个函数,它接受两个整数列表并返回一个包含所有笛卡尔积的列表。我认为我有正确的想法,但没有正确的实施。可以指点一下吗?

let rec cartesian = function
 | ([],[]) -> []
 | (xs,[]) -> []
 | ([],ys) -> []
 | (x::xs,ys) ->   List.map(fun y -> (x,y)::[]) cartesian (xs,ys) 

【问题讨论】:

  • 更不用说处理这种情况的代码已经存在于 FSSnip 上。

标签: f# f#-interactive f#-scripting


【解决方案1】:

这是一个快速修复:

let rec cartesian = function
 | ([],[]) -> []
 | (xs,[]) -> []
 | ([],ys) -> []
 | (x::xs, ys) -> (List.map(fun y -> x,y) ys) @ (cartesian (xs,ys))

这个想法是,对于每个元素 x,您会生成一个列表 [(x, y1); (x, y2); ...; (x, yn)] 并将这些列表连接在一起。

在您的函数中,第一个模式匹配案例是多余的。并且参数更方便地采用柯里化形式。该函数可能如下所示:

let rec cartesian xs ys = 
  match xs, ys with
  | _, [] -> []
  | [], _ -> []
  | x::xs', _ -> (List.map (fun y -> x, y) ys) @ (cartesian xs' ys)

一旦理解了思路,就可以看到高阶函数List.collect完美匹配任务:

let cartesian xs ys = 
    xs |> List.collect (fun x -> ys |> List.map (fun y -> x, y))

【讨论】:

  • 能否请您解释一下这部分 List.map(fun y -> x,y) ys) ...我也对 list.map 函数如何知道要使用哪个列表感到困惑。在这种情况下是 ys 而不是 xs
  • 您正在分解 xs,因此对于每个元素 x,您需要遍历整个 ys 以创建对 (x, yi) 的列表。最后,结果是所有对 (xi, yi) 的列表,其中 xi 来自第一个列表,yi 来自第二个列表。
  • 酷,感谢您的详细解释。
猜你喜欢
  • 1970-01-01
  • 2012-01-03
  • 2021-02-18
  • 2016-11-22
  • 2012-02-24
  • 2011-09-18
  • 2019-10-10
  • 2021-01-25
  • 2015-07-29
相关资源
最近更新 更多