【发布时间】:2021-07-06 11:19:16
【问题描述】:
我目前正在做一个项目,我有像[T;A;C;G;G;C;T;A;G;A;T;T;T;A;C;G;C;T;A;A;T;A;T;C] 这样的核苷酸 DNA 列表,我需要将第一条链(“START”和“STOP”)之间的核苷酸转换成相应的酸。因此,为此我需要获取 3 个 3 个核苷酸并将它们传递给这个函数:
type acid = Ala | Arg | Asn | Asp | Cys
| Glu | Gln | Gly | His | Ile
| Leu | Lys | Phe | Pro | Ser
| Thr | Trp | Tyr | Val | START | STOP
let convert_acid (n1 : nucleotide) (n2 : nucleotide) (n3 : nucleotide) : acid =
begin match (n1, n2, n3) with
| (A, A, A) -> Phe | (A, A, G) -> Phe | (A, A, T) -> Leu | (A, A, C) -> Leu
| (G, A, A) -> Leu | (G, A, G) -> Leu | (G, A, T) -> Leu | (G, A, C) -> Leu
| (T, A, A) -> Ile | (T, A, G) -> Ile | (T, A, T) -> Ile | (T, A, C) -> START
| (C, A, A) -> Val | (C, A, G) -> Val | (C, A, T) -> Val | (C, A, C) -> Val
| (A, G, A) -> Ser | (A, G, G) -> Ser | (A, G, T) -> Ser | (A, G, C) -> Ser
| (G, G, A) -> Pro | (G, G, G) -> Pro | (G, G, T) -> Pro | (G, G, C) -> Pro
| (T, G, A) -> Thr | (T, G, G) -> Thr | (T, G, T) -> Thr | (T, G, C) -> Thr
| (C, G, A) -> Ala | (C, G, G) -> Ala | (C, G, T) -> Ala | (C, G, C) -> Ala
| (A, T, A) -> Tyr | (A, T, G) -> Tyr | (A, T, T) -> STOP | (A, T, C) -> STOP
| (G, T, A) -> His | (G, T, G) -> His | (G, T, T) -> Gln | (G, T, C) -> Gln
| (T, T, A) -> Asn | (T, T, G) -> Asn | (T, T, T) -> Lys | (T, T, C) -> Lys
| (C, T, A) -> Asp | (C, T, G) -> Asp | (C, T, T) -> Glu | (C, T, C) -> Glu
| (A, C, A) -> Cys | (A, C, G) -> Cys | (A, C, T) -> STOP | (A, C, C) -> Trp
| (G, C, A) -> Arg | (G, C, G) -> Arg | (G, C, T) -> Arg | (G, C, C) -> Arg
| (T, C, A) -> Ser | (T, C, G) -> Ser | (T, C, T) -> Arg | (T, C, C) -> Arg
| (C, C, A) -> Gly | (C, C, G) -> Gly | (C, C, T) -> Gly | (C, C, C) -> Gly
end
所以我的想法是获取列表的前 3 个核苷酸,通过将它们传递给函数来转换它们,并将返回的列表连接成一个新列表,但我不知道该怎么做。这是我到目前为止在伪代码中所做的:
let rec dna_to_chain (x : dna) : acid list =
match with x
| hd::tl -> convert_acid hd
| _ -> do nothing
我想获取列表 x 的前 3 个元素,将它们传递给 convert_acid 函数,然后用列表的其余部分调用 dna_to_chain,直到我到达“STOP”酸。
之后,我需要执行另一个函数将每个 dna 转换为链(START 和 STOP 之间的每个核苷酸序列),并将它们放入具有类似功能的酸列表中,而不使用递归(我猜我需要使用我首先需要做的递归函数)。
有人知道我怎样才能完成我的代码并让它工作吗?谢谢!
编辑: 我现在有以下功能
let rec dna_to_chain (x : dna) : acid list =
match with x
| n1::n2::n3::tl -> (convert_acid n1 n2 n3) :: dna_to_chain tl
| [] -> [] ;;
dna_to_chain [T;A;C;G;G;C;T;A;G;A;T;T ; T;A;C;G;C;T;A;A;T;A;T;C] 返回[START; Pro; Ile; STOP ; START;Arg;Leu;STOP] 但我怎样才能在第一个开始和停止之间获得第一个酸?我正在考虑创建另一个函数并再次进行模式匹配,但是我怎么知道我匹配的 START 是例如链的第一个?
【问题讨论】:
-
这听起来像是家庭作业。您的模式
hd :: tl仅匹配第一个核苷酸 (hd)。您可能会考虑使用nt1 :: nt2 :: nt3 :: tl之类的模式来查看其中的三个。您可以将 3 个核苷酸翻译成酸。您还需要翻译尾部,即,您需要使用tl进行某种递归调用。然后你可以把这两个结果放在一起。 -
谢谢,这就是我想要的!我不知道这是可能的。现在我匹配 n1::n2::n3::tl -> (convert_acid n1 n2 n3) :: dna_to_chain tl.我不知道如何只获得 START 和 STOP 之间的第一个序列。我正在考虑创建第一个函数来执行带有 START 和 STOP 的转换,以及第二个函数仅将酸保持在 START 和 STOP 之间。我不确定这是否是正确的方法。
-
请注意,您的
dna_to_chain函数的模式匹配并不详尽。它不考虑具有 1 个或 2 个元素的列表。此外,它的风格,但我发现首先匹配空列表案例非常有帮助(并且通常是惯用的)。
标签: list recursion functional-programming pattern-matching ocaml