2012-02-16 6 views
4

[I [1; 2; 3]; [2]; [3; 4; 5; 6]과 같은 목록의 목록이 있습니다. [7; 8; 9; 10] 키가 목록의 길이이고 값이 주어진 길이의 모든 하위 목록을 포함하는 목록의 목록 인 Hashtbl에 이들을 배치하려고합니다.if 문과 Ocaml 오류

그래서 해시 위의 예는 나는 또한 긴 목록의 길이의 트랙을 유지하기 위해 노력하고 또한

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 [email protected][h]) (* Line 660 *) 
           else (Hashtbl.add hash len [h])); 

           (collector (max len curmax) t) 
     in 
     collector 0 lst 
    ;; 

는 지금은 OCaml의이 목록 '의 반환 형식을 요구하는 이유는 무엇

File "all_code.ml", line 600, characters 50-72: 
Error: This expression has type unit but an expression was expected of type 
    'a list 

위의 코드에 대한 다음과 같은 오류가 발생하고 어떻게이 문제를 해결 않습니다. 사전에 감사 Puneet

+1

코드를 들여 쓰기 (대부분의 편집자가 당신을 도울 수 있습니다)하고 쓸데없는 괄호를 제거하십시오 (토마스의 코드 참조). OCaml은 필요할 때만 글쓰기에 익숙해지면 읽기에 아름답습니다. –

+0

'Hashtbl.mem ... then v = Hashtbl.find ...'는 낭비입니다 (왜냐하면'Hashtbl'은'Hashtbl.mem'과'Hashtbl.find'에서 한번씩 요소를 두 번 찾아야하기 때문입니다). 나중에 불변성을 제거하는 방식으로 코드를 재구성 할 수 있다는 점에서 "안전하지 않음"입니다. 키가 존재할 때만 Hashtbl.find를 호출합니다. 'Hashtbl.find ... Not_found -> ... '를 사용하면 더 빠르고 오류가 없습니다. – Ashe

답변

4

당신은 아마 (Hashtbl.add hash len v)@[h]

로 분석 한 피하기 위해 ([email protected][h])에 괄호를 추가해야합니다 그리고 당신은 아마 Hashtbl.create-123456하지만, 307 또는 2017

4

같은 합리적인 소수를 통과하지한다 거의 다 왔어. @은 적용보다 우선 순위가 낮으므로 Basil이 말한대로 Hashtbl.add hash len [email protected][h](Hashtbl.add hash len v)@[h]으로 분석됩니다. 또한, 너무 많은 괄호를 사용하고 있습니다. if ((Hashtbl.mem hash len)=true)은 불필요합니다. 그래서 함수를 작성하기 위해 가능한 좋은 방법은 다음과 같습니다 업데이 트에서 OCaml의 거대 혜택 해시 테이블에

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 ([email protected][h]) 
     else 
     Hashtbl.add hash len [h]; 
     collector (max len curmax) t in 
    collector 0 lst 
4

대부분의 무거운 작업 원시적. 실제로 값이 테이블에 존재하는지 여부에 따라 다른 작업을 수행하는 두 가지 버전이 있습니다. 이것은 당신이 사용하고자하는 하나입니다 목록을 통과하고 모든 것을 추가, 거기에서

let prepend hashtbl key item = 
    update hashtbl key [] (fun list -> item :: list) 

:

(* 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' 

이러한 기본 요소로,이 해시 테이블의-목록을 관리하기 위해 간단하게 해시 테이블은 매우 간단합니다 :