Syntax OCaml中的游程解码
在我下面的函数中,lp的形式如示例[0,a;3,r;7,p;2,a]所示 函数run_length_decode接受lp并在上面的示例中返回[r;r;r;p;p;p;p;a;a]Syntax OCaml中的游程解码,syntax,ocaml,Syntax,Ocaml,在我下面的函数中,lp的形式如示例[0,a;3,r;7,p;2,a]所示 函数run_length_decode接受lp并在上面的示例中返回[r;r;r;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_decod
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,则打印要显示的字母,并递归调用RUNLENGTHDECODE,其中lp的头部递减并与lp的尾部连接。上述代码不起作用。问题是什么?如何修复?它可以帮助您:
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 []
;;
说明:
- acc是一个累加器
- aux是一个辅助功能
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 []
;;
说明:
- acc是一个累加器
- aux是一个辅助功能
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
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
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']
(我不明白为什么需要一个累加器或辅助函数——尽管它可能更有效,因为它是尾部递归的——而另一个答案没有给出该函数的明确版本。因此:)
如果我试图尽可能接近问题中的有缺陷代码,我会得到:
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']
你说代码不起作用。到底是什么问题?注意,本地名称在OCaml中必须以小写字母开头。实际上不能有名为
RUNLENGTHDECODE
的函数。如果你坚持使用大量的大写字母,你可以将其命名为rUNLENGTHDECODE
。就我个人而言,我会把它命名为run\u length\u decode
。如果你说代码不起作用,你可能想看看。到底是什么问题?注意,本地名称在OCaml中必须以小写字母开头。实际上不能有名为RUNLENGTHDECODE
的函数。如果你坚持使用大量的大写字母,你可以将其命名为rUNLENGTHDECODE
。就我个人而言,我会把它命名为run\u length\u decode
。你可能想看看aux和acc是什么意思?@ML.acc是一个累加器,一个辅助函数。@V.Michel如何传递内部函数的输入?@ML.via fold_left.aux和acc是什么意思?@ML.acc是一个累加器,一个辅助函数。@V.Michel输入到内部函数是如何传递的?@ML.通过fold_left.澄清一下,输入列表[0,a;3,r;7,p;2,a]
实际上是一个元组列表[(0,a);(3,r);(7,p);(2,a)]
——注意,
和之间的区别代码>。为了澄清,输入列表[0,a;3,r;7,p;2,a]
实际上是一个元组列表[(0,a);(3,r);(7,p);(2,a)]
——注意,
和之间的区别代码>。