3

我对 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

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

4

1 回答 1

6

你基本上只是缺少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(当列表为空时)并将列表拆分为头部和尾部。假设你有尾巴的总和(你可以递归地得到),答案很明显。你只需要把头加到这个总和上。你只需要问自己(几乎总是):如果我有列表尾部的答案,我需要做什么才能将它与头部结合起来?

于 2013-01-27T05:01:13.457 回答