我正在Ocaml中实现一种方法,以对随机类型'a的列表执行行程编码数据压缩。 列表中相同的连续元素将压缩为提供的代码开头定义的类型。我提供的代码无效。我认为这行不通的原因之一是,如果您查看第一个匹配项的大卡盘之间的新行,则新行之后的匹配项应属于较高匹配项。但是,Learn Ocaml中的编译器无法识别这一点。它将剩余的匹配语句(本来应该是第一个匹配项)自动分组到嵌套的match语句中。
这是Ocaml tutorial website(问题13)中的消费税之一: “直接实施所谓的行程编码数据压缩方法。即,没有明确创建包含重复项的子列表,如问题“将列表元素的连续重复项包装到子列表中”,而仅对其进行计数。如问题“修改的行程编码”,通过用X替换单例列表(1 X)来简化结果列表。”
type 'a rle =
| One of 'a
| Many of int * 'a;;
let encodeDirect (l: 'a list)=
let rec helper current acc ll=
match ll with
|[] -> current::acc
|[a]-> match current with
|None -> (Some(One a))::acc
|Some(One q) -> (Some(Many(2,q)))::acc
|Some(Many(t,y)) -> (Some(Many(t+1,y)))::acc
|a::(m::ls as e) -> if a=m then match current with
|None -> helper (Some(One a)) acc e
|Some(One q) -> helper (Some(Many(2,q))) acc e
|Some(Many(t,y)) -> helper (Some(Many(t+1,y))) acc e
else match current with
|None -> helper None (Some(One a)::acc) e
|Some(One q) -> helper None (Some(Many(2,q))::acc) e
|Some(Many(t,y)) ->helper None (Some(Many(t+1,y))::acc) e
in helper None [] l
以下是其工作方式的示例: 编码[“ a”;“ a”;“ a”;“ a”;“ b”;“ c”;“ c”;“ a”;“ a”;“ d”;“ e”;“ e”; “ e”;“ e”] ;; -:字符串列表= [许多(4,“ a”);一个“ b”;许多(2,“ c”);许多(2,“ a”);一个“ d”; 许多(4,“ e”)]
答案 0 :(得分:0)
我经常在嵌套match
时遇到相同的问题。您可以通过在内部匹配项中加上括号来解决该问题。
type 'a rle =
| One of 'a
| Many of int * 'a;;
let rec helper current acc ll=
match ll with
|[] -> current::acc
|[a]->
(match current with
|None -> (Some(One a))::acc
|Some(One q) -> (Some(Many(2,q)))::acc
|Some(Many(t,y)) -> (Some(Many(t+1,y)))::acc
)
|a::(m::ls as e) ->
if a=m then
match current with
|None -> helper (Some(One a)) acc e
|Some(One q) -> helper (Some(Many(2,q))) acc e
|Some(Many(t,y)) -> helper (Some(Many(t+1,y))) acc e
else
match current with
|None -> helper None (Some(One a)::acc) e
|Some(One q) -> helper None (Some(Many(2,q))::acc) e
|Some(Many(t,y)) ->helper None (Some(Many(t+1,y))::acc) e