复杂数据结构 ocaml 上的模式匹配



我是OCaml的新手,所以我在基础知识方面遇到了一些麻烦。对于我的程序,我必须将核苷酸与其补体(G -> C,C -> G,A -> T,T -> A)相匹配,以便找到双螺旋的另一半。一般的想法是DNA由2个互补螺旋组成,每个螺旋都是一个核苷酸序列。目前,我正在尝试计算双螺旋的另一半。

到目前为止,我已经用枚举表示了核苷酸,并且用对应于一个螺旋的核苷酸列表表示了DNA。

type nucleotide = 
| G 
| C 
| A 
| T
type helix = nucleotide list
let rec complementary_helix (x:helix): helix =
| [G] -> [C]
| [C] -> [G]
| [A] -> [T]
| [T] -> [A]
end

我知道这里缺少一些东西,但我不知道该怎么做。有人能引导我朝着正确的方向前进吗?

你基本上只是缺少List.map

let complement = function
| G -> C
| C -> G
| A -> T
| T -> A
let complementary_helix (x: helix) : helix =
    List.map complement x

(对于它的价值,没有必要指定类型。OCaml 将推断类型。为文档指定它们是很好的风格,但如果它们很明显,则可能不是。

编辑

好的,我想这是一个家庭作业问题,你应该使用递归来解决问题。

考虑递归的方法是你想解决问题的一小部分,这给了你一个更小的问题来解决。你把较小的问题交给自己(在你解决你的小问题之前或之后)。您还需要知道问题何时变得如此之小,以至于没有更多的工作要做。

在你的情况下,一小块是将一个核苷酸翻译成它的补体。你正在做这个半OK(你有列表,你真的只想研究单个核苷酸)。但是你并没有把问题的其余部分交给自己递归解决。你也没有检查问题是否太小以至于无事可做。

对于列表上的函数,大约 99% 的情况下,您将通过将列表拆分为头部(单个元素)和尾部(小一的列表)来缩小问题。这将在这里为您工作。

编辑 2

作为列表递归外观的示例,下面是一个将列表中所有整数相加的函数:

let rec sum l =
    match l with
    | [] -> 0
    | head :: tail -> head + sum tail

这包含我描述的所有部分。match既用于判断问题何时微不足道(当列表为空时),也用于将列表拆分为头部和尾部。假设你有尾巴的总和(你可以递归得到),答案是显而易见的。你只需要把头加到这个总和上。你只需要问问自己(几乎总是):如果我有列表尾部的答案,我需要怎么做才能将其与头部结合起来?

最新更新