f#越界异常,因为列表理解产生的结果超出了我的预期
我正在制作一个函数,它获取一个映射并生成所有可能的值交换f#越界异常,因为列表理解产生的结果超出了我的预期,f#,F#,我正在制作一个函数,它获取一个映射并生成所有可能的值交换 let mutations setup = let setupList = setup |> Map.toList [for x in 0..(setupList.Length-1) do for y in x..(setupList.Length-1) do yield (x, y)] |> Seq.map (fun (x,y) -> setupList |> sw
let mutations setup =
let setupList = setup |> Map.toList
[for x in 0..(setupList.Length-1) do
for y in x..(setupList.Length-1) do
yield (x, y)]
|> Seq.map (fun (x,y) ->
setupList
|> swapSndAt x y
|> Map.ofList)
|> Seq.distinct
以下是swapsnad
的代码:
let swapSndAt i1 i2 xs =
let f1,s1 = xs |> List.item i1
let f2,s2 = xs |> List.item i2
xs |> List.mapi (fun i x ->
if i = i1 then f1,s2
else if i = i2 then f2,s1
else x)
运行此操作时,我得到一个System.ArgumentException:索引超出了列表中的元素范围。
在swapsnadat
中调用list.item
既然列表理解确保观察边界,那怎么可能呢?你确定这是你想要的吗?例如
让l=[((“a”,1);(“b”,2);(“c”,3)]|>Map.ofList
<代码>突变l |>Seq.toList给我:val it:(int*int)list=[(0,0);(0,1);(0,2);(1,1);(1,2);(2,2)]
你的代码对我来说非常有效。也许这在某些特定的输入上失败了?如果是这样的话,你愿意分享这个输入吗?与问题无关:你可能想考虑把代码在<代码> SEQ。确实不需要将其作为单独的调用,看起来很难看。是否确实要使用Map.toList
而不是Map.toArray
?您正在反复调用List.item
(一个O(N)操作)(大约O(N^2)次),这使您的整体算法为O(N^3)。您最好使用数组,因为为数组编制索引是一个固定时间,您的总体运行时间将减少到O(N^2)。@FyodorSoikin证明,代码正如您所说的是正确的。旧版本的代码没有检查边界,我也没有正确地将函数重新加载到f#interactive中;对不起,提出了不必要的问题。我应该删除这个问题吗?