在OCaml中组合一列列表

时间:2016-04-17 04:52:06

标签: ocaml

我想基本上在OCaml中转置一个矩阵(不使用递归或任何类型的循环)

例如,如果我有以下矩阵:[[1;2];[3;4]]
我希望得到[[1;3];[2;4]]的输出。

到目前为止我所做的是将原始矩阵分解为单个列:

//function that separates into cols
let separate li =
    List.map (fun x -> [x]) li;;

我从另一个函数调用这个辅助函数:

let trans x = 
    List.concat (List.map separate li) x;;

我认为这会按照我想要的方式组合所有列,而是以下列输出结束:[[1];[2];[3];[4]]

2 个答案:

答案 0 :(得分:0)

我怀疑你的#---------------------------------------------------------------- # Definition of the physical layer #---------------------------------------------------------------- set val(chan) Channel/WirelessChannel set val(prop) Propagation/TwoRayGround set val(netif) Phy/WirelessPhy set val(mac) Mac/802_11 set val(ifq) Queue/DropTail/PriQueue set val(ll) LL set val(ant) Antenna/OmniAntenna #----------------------------------------------------------------- # Scenario parameters #------------------------------------------------------------------ set val(x) 2000 ;# X dimension of the topography set val(y) 2000 ;# Y dimension of the topography set val(ifqlen) 100 ;# max packet in queue set val(seed) 0.0 ;#random seed set val(adhocRouting) DSR ; set val(nn) 50 ;# how many nodes are simulated set val(cp) < cbr file > set val(sc) < scen file > set val(stop) 200 ;# simulation time #--------------------------------------------------------------------- # Set up simulator objects #--------------------------------------------------------------------- # create simulator instance set ns_ [new Simulator] # setup topography object set topo [new Topography] # create trace object for ns and nam set tracefd [open out.tr w] $ns_ use-newtrace ;# use the new wireless trace file format set namtrace [open out.nam w] $ns_ trace-all $tracefd $ns_ namtrace-all-wireless $namtrace $val(x) $val(y) # define topology $topo load_flatgrid $val(x) $val(y) # Create God set god_ [create-god $val(nn)] $ns_ node-config -adhocRouting $val(adhocRouting) \ -llType $val(ll) \ -macType $val(mac) \ -ifqType $val(ifq) \ -ifqLen $val(ifqlen) \ -antType $val(ant) \ -propType $val(prop) \ -phyType $val(netif) \ -channelType $val(chan) \ -topoInstance $topo \ -agentTrace ON \ -routerTrace ON \ -macTrace ON # Create the specified number of nodes [$val(nn)] and "attach" them # to the channel. for {set i 0} {$i < $val(nn) } {incr i} { set node_($i) [$ns_ node] #$ns at 0.0 "$node_(0) color blue" $node_($i) random-motion 0 ;# disable random motion } for {set i 0} {$i < $val(nn) } {incr i} { $node_($i) color blue $ns_ at 0.0 "$node_($i) color cyan" } # Define node movement model puts "Loading connection pattern..." source $val(cp) # Define traffic model puts "Loading scenario file..." source $val(sc) # Define node initial position in nam for {set i 0} {$i < $val(nn)} {incr i} { # 50 defines the node size in nam, must adjust it according to your scenario # The function must be called after mobility model is defined # puts "Processing node $i" $ns_ initial_node_pos $node_($i) 50 } # # Tell nodes when the simulation ends # for {set i 0} {$i < $val(nn) } {incr i} { $ns_ at $val(stop).0 "$node_($i) reset"; } $ns_ at $val(stop).0002 "puts \"NS EXITING...\" ; $ns_ halt" # dump the initial simulation info to the trace file puts $tracefd "M 0.0 nn $val(nn) x $val(x) y $val(y) rp $val(adhocRouting)" puts $tracefd "M 0.0 sc $val(sc) cp $val(cp) seed $val(seed)" puts $tracefd "M 0.0 prop $val(prop) ant $val(ant)" puts "Starting Simulation..." $ns_ run 函数是否将矩阵分成列。这就是我所看到的:

separate

我没有看到专栏,我只是看到您已将每个矩阵元素放入其自己的列表中。

要获得第一列,您可以尝试这样做:

# let separate li = List.map (fun x -> [x]) li;;
val separate : 'a list -> 'a list list = <fun>
# List.map separate [[1;2];[3;4]];;
- : int list list list = [[[1]; [2]]; [[3]; [4]]]

如果您使用# List.map List.hd [[1;2]; [3;4]];; - : int list = [1; 3] 而不是List.tl,则会获得行的剩余部分。也许你可以使用折叠重复应用它并收集结果。

答案 1 :(得分:0)

假设您的列表列表是矩形的,this Standard ML code会转换为OCaml:

let rec transpose xss =
    match xss with
        | [] -> []
        | []::_ -> []
        | _ -> List.map List.hd xss :: transpose (List.map List.tl xss)

在删除已经提取的列(List.map List.hd xss)后,它会提取第一列(List.map List.tl xss)并递归地将其与剩余列的提取相结合。

仍然保留在此函数中的显式递归不能轻易地被映射/折叠替换,因为这些将一次寻址一行,其中上面的递归方案一次解决所有行的一部分(一部分)。 unfolding / anamorphism可能会有更多的运气:

let rec unfold f a =
    match f a with
    | Some (b, a') -> b :: unfold f a'
    | None -> []

val unfold : ('a -> ('b * 'a) option) -> 'a -> 'b list = <fun>

其中'a可以逐渐减少输入行矩阵,'b矩阵列:

let transpose =
    unfold (function
            | [] -> None
            | []::_ -> None
            | m -> Some (List.map List.hd m, List.map List.tl m))