我有一份清单,例如[[1; 2; 3]; [2]; [3; 4; 5; 6]; [7; 8; 9; 10] 我想将它们放在Hashtbl中,其中键是列表的长度,值是列表列表,其中包含给定长度的所有子列表。
因此,对于上面的示例,哈希将如下所示
Key Value
1 [[2]]
3 [[1;2;3]]
4 [[3;4;5;6];[7;8;9;10]]
此外,我还试图跟踪最长列表的长度,该数字是函数返回的数字
执行此操作的代码如下。
let hashify lst =
let hash = Hashtbl.create 123456 in
let rec collector curmax lst =
match lst with
[] -> curmax
| h::t -> let len = (List.length h) in
(if ((Hashtbl.mem hash len)=true)
then ( let v = (Hashtbl.find hash len) in Hashtbl.add hash len v@[h] ) (* Line 660 *)
else ( Hashtbl.add hash len [h]));
(collector (max len curmax) t)
in
collector 0 lst
;;
现在当我这样做时,上面的代码出现以下错误
File "all_code.ml", line 600, characters 50-72:
Error: This expression has type unit but an expression was expected of type
'a list
为什么Ocaml需要返回类型的'列表,我该如何解决这个问题。 提前致谢 普尼特
答案 0 :(得分:4)
您可能应该在(v@[h])
中添加括号,以避免将其解析为(Hashtbl.add hash len v)@[h]
您可能不应该将123456传递给Hashtbl.create
,而应该将合理的素数传递给307或2017
答案 1 :(得分:4)
你几乎就在那里:@
的优先级低于apply,因此,正如Basil所说,Hashtbl.add hash len v@[h]
被解析为(Hashtbl.add hash len v)@[h]
。而且,你使用太多括号,if ((Hashtbl.mem hash len)=true)
是不必要的冗长。因此,编写函数的可能方法是:
let hashify lst =
let hash = Hashtbl.create 307 in
let rec collector curmax = function
| [] -> curmax
| h::t ->
let len = List.length h in
if Hashtbl.mem hash len then
let v = Hashtbl.find hash len in
Hashtbl.add hash len (v@[h])
else
Hashtbl.add hash len [h];
collector (max len curmax) t in
collector 0 lst
答案 2 :(得分:4)
OCaml中对哈希表的大量工作极大地受益于更新原语。实际上有两个版本,它们根据表中是否存在值来执行不同的操作。这是你想要使用的那个:
(* Binds a value to the key if none is already present, and then updates
it by applying the provided map function and returns the new value. *)
let update hashtbl key default func =
let value = try Hashtbl.find hashtbl key with Not_found -> default in
let value' = func value in
Hashtbl.remove hashtbl key ; Hashtbl.add hashtbl key value' ; value'
使用这些原语,管理列表哈希表变得简单:
let prepend hashtbl key item =
update hashtbl key [] (fun list -> item :: list)
从那里,遍历列表并将所有内容附加到哈希表非常简单:
let hashify lst =
let hash = Hashtbl.create 607 in
List.fold_left (fun acc list ->
let l = List.length list in
let _ = prepend hash l list in
max acc l
) 0 lst