在我的函数中,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的尾部连接。上面的代码不起作用。有什么问题?怎么解决?
答案 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']
解释:
答案 1 :(得分:1)
您似乎希望使用List.hd
和List.tl
来分解构成输入列表元素的(3,r)
元组。问题是元组不是列表。由于元组是成对的,您可以使用fst
和snd
进行分解。
就个人而言,我建议使用模式匹配,如下所示:
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']