在OCaml中运行长度解码

时间:2017-01-18 04:51:38

标签: syntax ocaml

在我的函数中,lp的形式如例子[0,a; 3,r; 7,p; 2,a]。

函数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的RUNLENGTHDECODE,其中lp的头部递减并与lp的尾部连接。上面的代码不起作用。有什么问题?怎么解决?

3 个答案:

答案 0 :(得分: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是辅助功能

答案 1 :(得分: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),但可能不是你想要的。

答案 2 :(得分: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']