我目前正在矩阵上练习,但我并不确定以最有效的方式来解决我遇到的一些问题。
我的第一个"问题"是优化功能。我尝试做的是迭代一个矩阵,这是一个阵列数组。 对于由0到4之间的整数标识的每一行(矩阵的大小为(5,10)),我计算了多少"一个"有。。
我不得不将它分成三个不同的功能,但我想知道是否有更优化的方法来解决这个问题?
let count m i =
let ret=Array.fold_left (fun x y -> if y=1 then x+1 else x) 0 (m.(i)) in
ret;;
let rec clear l =
match l with
|[]->[]
|(a,b)::[]->if b=0 then [] else (a,b)::[]
|(a,b)::c->if b=0 then clear c else (a,b)::clear c;;
let all_moves s =
match s with
|(a,_)->clear[(0,count a 0);(1,count a 1);(2,count a 2);(3,count a 3);(4,count a 4)];;
其次,我的主要问题是立即迭代整个矩阵。 我试图计算矩阵中的所有1,除了由param" i"标识的行。 我尝试了几件事,但我现在真的陷入困境。
let countall m i =
let ret=Array.fold_left (fun x y -> if pos != i then x + y else ())
(Array.fold_left (fun x y -> if y=1 then x+1 else x) 0 (m.(i)))
0 m in
ret;;
我想提前感谢你的帮助,我想我可能会给你一个矩阵来测试我的功能:
let c = [|[|1; 1; 1; 1; 1; 0; 0; 0; 0; 0|]; [|1; 1; 1; 1; 1; 1; 1; 1; 0; 0|];
[|1; 1; 1; 1; 1; 1; 1; 1; 1; 0|]; [|1; 0; 0; 0; 0; 0; 0; 0; 0; 0|];
[|1; 1; 1; 1; 1; 1; 1; 1; 1; 1|]|]
真诚的,你的, 拉马
答案 0 :(得分:0)
也许这可以帮到你
let countall m i =
snd (
Array.fold_left (fun (lg,c) v ->
let c=
if lg = i then c
else
Array.fold_left (fun c xy -> if xy=1 then c+1 else c) c v
in
(lg+1,c)
) (0,0) m
)
;;
测试
# countall c 0;;
- : int = 28
答案 1 :(得分:0)
一些指示:
let ret = expr in ret
的表达式可以简化为expr
。反向应用程序运算符|>
通常可用于忽略琐碎的let
表达式。let all_moves s = match s with (a, _) -> ...
变为`let all_moves(a,_)= ...'。Array
和List
模块不仅具有折叠功能(以及替代标准库,例如Core,Batteries或ExtLib为它们添加更多功能),可用于简化许多数组/列表处理。示例:
let count_ones row =
Array.fold_left (fun c x -> if x=1 then c+1 else c) 0 row
let all_moves (mat, _) =
Array.mapi (fun i row -> (i, count_ones row)) mat
|> Array.to_list |> List.filter (fun (_, c) -> c != 0)
我不是100%确定countall
的预期语义是什么,但如果我正确理解它,则以下内容应该有效(它遵循您尝试的解决方案的基本结构,但依赖于{ {1}}而不是mapi
,这是更合适的选择):
fold_left
这个功能也可以用不同的方式实现,例如:
let countall mat k =
Array.mapi (fun i row -> if i = k then 0 else count_ones row) mat
|> Array.fold_left (+) 0
在此变体中,我使用本地开放let countall mat k =
Array.(append (sub mat 0 k) (sub mat (k+1) (length mat - k - 1)))
|> Array.map count_ones |> Array.fold_left (+) 0
,因此我不必为每个单独的数组操作添加前缀Array.(expr)
。此外,在两个版本中Array.
都是将plus运算符编写为具有两个参数的函数的方法,并且大致相当于在其位置编写(+)
。