2017-01-18 34 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的头部较大然后打印要显示的字母并递归调用具有修改的lp的RUNLENGTHDECODE,其中lp的头部递减并与lp的尾部连接。上面的代码不起作用。什么是问题?怎么修?

+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为蓄能
  • AUX是辅助功能
+0

aux和acc是什么意思? –

+0

@ML。 ACC是一个辅助功能的累加器。 –

+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

(我不明白为什么需要累加器或辅助函数 - 尽管它可能效率更高,因为它是尾递归的 - 而另一个答案不提供函数的显式版本这样可行。因此:)

如果我尽量保持尽可能接近,从问题的有缺陷的代码,我得到:

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']