我需要生成1..n x 1..n的所有不同排列的列表,其中第一个值不等于第二个 (即产生3 - > [(3,2)::(3,1)::(2,3)::(2,1)::(1,3)::(1,2)] < / p>
确切的情况是你有一个对象池(卡片),每个玩家都有一个。如果一名牌手被发牌,那么其他牌手就不会被发牌(暂时忽略套牌,如果必须的话,我会让1-52牌照到实际的牌上)
我想出了以下看起来很混乱的内容
let GenerateTuples (numcards: int) =
let rec cellmaker (cardsleft: int) (cardval:int) =
if cardval = cardsleft then (if cardval <= 0 then [] else cellmaker cardsleft (cardval-1) ) elif cardval <= 0 then [] else (cardsleft, cardval) :: cellmaker cardsleft (cardval-1)
let rec generatelists (cardsleft:int) =
cellmaker cardsleft numcards @ (if cardsleft > 1 then generatelists (cardsleft-1) else [])
generatelists numcards
有更好的方法吗?
答案 0 :(得分:6)
您可以使用列表推导轻松完成:
let GenerateTuples (n:int) =
[for i in 1..n do for j in 1..n do if i <> j then yield (i,j)]
答案 1 :(得分:0)
这个问题最好被看作是一个矩阵问题,而命令式解决方案的嵌套“for”循环可以在功能上完成。
let Permute n =
let rec Aux (x,y) =
if (x,y) = (n,n) then
[]
else
let nextTuple = if y = n then ((x + 1),1) else (x,(y + 1))
if x = y then
Aux nextTuple
else
(x,y)::(Aux nextTuple)
Aux (1,1)
这不是尾递归的,所以在我的机器上得到大约n = 500的堆栈溢出。使这个函数尾递归几乎是微不足道的。
时间非常有趣。这个函数(尾递归版)比原版多50%,而命令式解决方案再次花了大约3倍的时间!是的 - 最初的功能解决方案是最快的,这是下一个最快的,而命令式列表理解是最慢的,大约1 :: 1.5 :: 4。测试了各种各样的数据集。