这些javascript DNA补充算法是否等同于&最佳?

时间:2015-10-25 22:07:18

标签: javascript regex string

典型的DNA碱基串的互补序列可以通过反转串然后用其补体替换每个碱基(A-> T,T-> A,C-> G,G-> C)来找到。 )。例如,CTTAACCAGCGGACACGGGCTTGGC的补体是GCCAAGCCCGTGTCCGCTGGTTAAG。

我在javascript中写了几个算法来做这个,我想知道它们是否等价,例如等效的时间复杂度,但也相当于在浏览器中查找补码和更新HTML文档的任何其他考虑因素。输出。我试图理解正则表达式以及如何解释,编译和执行javacript。

首先,脚本使用此正则表达式s验证输入字符串/[^CGAT]/。如果输入字符串具有除C,G,A或T之外的字符,则脚本将停止并警告用户原因。接下来,该脚本使用var reverseSeq=s.split('').reverse().join('') (which I found here)生成反向字符串。

然后这些javascripts中的任何一个将反转的字符串转换为原始的补充。

1)

var complementSeq='';
for (i in reverseSeq){complementSeq=complementSeq+COMPLEMENT_BASES[reverseSeq[i]]};

2)。

complementSeq=reverseSeq.replace(/(A)|(C)|(T)|(G)/g, function (match) {return COMPLEMENT_BASES[match]})

2)取决于这个对象:COMPLEMENT_BASES={'A':'T','T':'A','G':'C','C':'G'};

这些方法是否同样有效,否则基本相同?我还缺少其他可能更有效的方法吗?

3 个答案:

答案 0 :(得分:2)

您可以使用简化的 RegExp 加快速度,因为您并不真正需要捕获组

var COMPLEMENT_BASES = {'A': 'T', 'T': 'A', 'G': 'C', 'C': 'G'},
    re = /[ATCG]/g;

var complementSeq = reverseSeq.replace(re, function ($0) {
    return COMPLEMENT_BASES[$0]
});

您还可以通过使用更多预定义来减半+迭代次数。这虽然是线性速度的提高。即。

var COMPLEMENT_BASES = {
     'A':  'T',  'T':  'A',  'G':  'C',  'C':  'G',
    'AA': 'TT', 'AT': 'TA', 'AC': 'TG', 'AG': 'TC',
    'TA': 'AT', 'TT': 'AA', 'TC': 'AG', 'TG': 'AC',
    'CA': 'GT', 'CT': 'GA', 'CC': 'GG', 'CG': 'GC',
    'GA': 'CT', 'GT': 'CA', 'GC': 'CG', 'GG': 'CC'
};

var re = /[ATCG]{1,2}/g;

如果您要生成大量此类数据,请考虑 ATCG String 是否真的是最佳选择。例如,以下是使用整数更好吗?

__|_dec_|_bin_    <-- XOR -->    _bin_|_dec_|__
A |   0 |  00       (3) 11         11 |   3 | T
T |   3 |  11           11         00 |   0 | A
C |   1 |  01           11         10 |   2 | G
G |   2 |  10           11         01 |   1 | C

如果您跟踪序列长度,现在可以在 32位XOR 中进行此转换,因此每个 XOR 转换16个碱基。内存开销也减少了4。

在JavaScript中, XOR运算符^,即(0 ^ 3) === 3(1 ^ 3) === 2; // true

答案 1 :(得分:1)

算法的大O效率是相同的。所有这三种算法都是O(n)复杂度(其中n是输入的长度)。我个人无法想到它可能比这更好的方式,所以这一切都归结为分析代码,看看哪个更快。但有些事情需要考虑:

  1. 正则表达式具有较高的初始编译成本,因此如果这样 要被调用很多,你可能想要编译你的正则表达式。
  2. 在这种情况下,函数调用也可能很昂贵(他们必须这样做 建立堆栈等等,所以你可能想要远离 正则表达式因此而取代。
  3. 对于纯代码易读性,第一种方法赢得IMO(我理解的是高度主观性)。
  4. 要考虑的另一件事可能是一次跨越两到三个字母。同样,这必须进行分析,但您可以一次构建一个基于两个或三个字母及其补码的查找表。对于类似这样的事情,如果字符串长度足够大,循环操作和字符串连接操作可能是一个相当大的开销。

答案 2 :(得分:1)

我认为,您应该使用已存在的数组并在加入之前映射补码值。

替换和使用正则表达式的开销比你真正需要的更多。

&#13;
&#13;
function complement(a) {
    return { A: 'T', T: 'A', G: 'C', C: 'G' }[a];
}    

var sequence = 'CTTAACCAGCGGACACGGGCTTGGC',
    complementSeq = sequence.split('').reverse().map(complement).join('');
document.write(complementSeq);
&#13;
&#13;
&#13;