Syntax OCaml中的游程解码

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

在我下面的函数中,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_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)]
——注意
之间的区别