2017-01-18 2 views
0

아래 함수에서 lp는 [0, a; 3, r; 7, p; 2, a]와 같은 형식입니다.OCaml에서 런 길이 디코딩

run_length_decode 함수는 lp를 취하고 위의 예에서 [r; r; r; p; p; p; p; p; p; p; a; a]를 반환합니다.

let rec run_length_decode lp = match (List.hd lp) with [] ->[] 
| [0] -> rle_decode (List.tl (List.tl lp)) 
| _ -> (List.hd [List.tl]):: run_length_decode (List.hd (List.hd lp) -1)::(List.hd [List.tl])::(List.tl [List.tl]) 

그것은 몇 가지 오류가 말한다 (List.hd (List.hd LP) -1) 내가 머리와 감소 및을 할 위치 (List.hd [List.tl]) : :(List.tl [List.tl]) 여기에서 목록의 꼬리를 연결하여 감소 된 머리와 반복되도록하려는 경우.

아이디어는 (1) lp가 비어있는 경우 빈 종료를 반환하고, (2) lp의 헤드가 0이면 lp의 다음 섹션으로 건너 뜁니다. (3) lp의 헤드가 더 크면 0보다 작 으면 표시 할 문자를 인쇄하고 lp의 헤드가 감소되고 lp의 꼬리와 연결되는 수정 된 lp를 사용하여 RUNLENGTHDECODE를 재귀 적으로 호출합니다. 위의 코드가 작동하지 않습니다. 이슈가 뭐야? 어떻게 고치는 지?

+1

코드가 작동하지 않는다고합니다. 문제가 정확히 무엇입니까? 로컬 이름은 OCaml에서 소문자로 시작해야합니다. 실제로'RUNLENGTHDECODE'라는 함수를 가질 수는 없습니다. 대문자를 많이 쓰면'RUNLENGTHDECODE'라고 이름을 붙일 수 있습니다. 개인적으로 나는'run_length_decode'와 같은 이름을 붙일 것입니다. –

+1

https://ocaml.org/learn/tutorials/99problems.html#Decodearunlengthencodedlistmedium – ChriS

답변

1

그것은 당신을 도울 수 있습니다 :

let run_length_decode lp = 
    let rec aux (n,c) acc =  
    if n<=0 then acc else aux (n-1,c) (c::acc) 
    in 
    List.fold_right aux lp [] 
;; 

테스트 :

# run_length_decode [0,'a';3,'r';7,'p';2,'a'];; 
- : char list = ['r'; 'r'; 'r'; 'p'; 'p'; 'p'; 'p'; 'p'; 'p'; 'p'; 'a'; 'a'] 

설명 :

  • ACC는
  • 보조는 보조 기능
에게 인 축적이다
+0

aux와 acc는 무엇을 의미합니까? –

+0

@ ML. acc는 누산기이고 aux는 보조 함수입니다. –

+0

@ V.Michel 실제로 코드를 설명 할 수 있습니까? –

1

List.hdList.tl을 사용하여 입력 목록의 요소를 구성하는 (3,r)과 같은 튜플을 분해하는 것이 좋습니다. 문제는 튜플이 목록이 아니라는 것입니다. 튜플이 쌍이므로 분해를 수행하려면 fstsnd을 사용할 수 있습니다.

match lp with 
| [] -> ... 
| (repetitions,character) :: rest -> ... 

가 코드와 좀 더 문제가 될 것 같습니다 : 당신은 lp 유형 (int * char) list이다 것을 의미

  • 하지만이

    개인적으로 나는 패턴은 다음과 같이 대신 일치하는 것이 좋습니다 유형 일치 케이스 int list.

  • List.hd [whatever]은 바로 whatever과 같습니다. 대괄호는 목록 생성자입니다.
  • [List.tl] (임의의 인수가 List.tl으로 제공되지 않음)은 올바른 값 (유형이 (`a list -> `a list) list)이지만 원하는 것은 아닐 수도 있습니다.
+0

입력리스트'''[0, a; 3, r; 7, p; 2, a]'''는 실제 튜플의 목록입니다 (''[(0, a); (3, r); (7, p); (2, a)]'''-''','''''''''''의 차이점에 주목하십시오. –

0

(필자는 누적 기 또는 보조 기능이 필요할지 모릅니다. 꼬리 재귀 (tail-recursive)이기 때문에 아마 더 효율적 일지 모르지만, 다른 대답은 함수의 명시적인 버전을 제공하지 않습니다.) 그 작품.

let rec run_length_decode lp = match lp with [] ->[] 
| (0,_)::_ -> run_length_decode (List.tl lp) 
| _ -> (snd (List.hd lp)):: run_length_decode (((fst (List.hd lp) -1),(snd (List.hd lp)))::(List.tl lp)) 

그러나 나는 아마이에게 자신을 작성합니다 : 나는 질문에서 결함 코드에 최대한 가깝게 유지하려고하면 따라서 :)

, 내가 얻을

let rec run_length_decode lp = 
    match lp with 
    | [] -> [] 
    | (0,_)::lp' -> run_length_decode lp' 
    | (n,c)::lp' -> c::run_length_decode ((n-1,c)::lp') 

두 경우 모두 :

# run_length_decode [0,'a';3,'r';7,'p';2,'a'];; 
- : char list = ['r'; 'r'; 'r'; 'p'; 'p'; 'p'; 'p'; 'p'; 'p'; 'p'; 'a'; 'a']