DNA 有一个小字母表。您可以使用lookup table,将一些语句替换为简单的数组索引。
这种方法:
- 仅遍历序列一次。
- 消除条件语句。
- 可以在字母大小写方面保持稳定,有时用于在 DNA 序列中传达信息。
- 可以处理 IUPAC 歧义代码。
- 可以处理间隙。
- 可以很容易地提供一个反向补码。
首先,您需要一个查找表。
private static final String COMPLEMENT_TABLE
// 0123456789ABCDEF0123456789ABCDEF
= " " // 0-31
+ " - " // 32-63
+ " TVGH CD M KN YSAABWXR " // 64-95
+ " tvgh cd m kn ysaabwxr "; // 96-127
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
private static final byte[] COMPLEMENT_TABLE_BYTES
= COMPLEMENT_TABLE.getBytes( StandardCharsets.US_ASCII );
然后,您可以通过简单的查表找到补码的碱基。
public static byte[] complement( byte[] sequence ) {
int length = sequence.length;
byte[] result = new byte[ length ];
for ( int i = 0; i < length; ++i ) {
result[i] = COMPLEMENT_TABLE_BYTES[ sequence[i] ];
}
return result;
}
如果需要方便使用小序列,您可以提供一个接受并返回字符串的方法。
public static String complement( String sequence ) {
byte[] complementBytes = complement(
sequence.getBytes( StandardCharsets.US_ASCII ));
return new String( complementBytes, StandardCharsets.US_ASCII );
}
可以在同一个循环中计算反向补码。
public static byte[] reverseComplement( byte[] sequence ) {
int length = sequence.length;
byte[] result = new byte[ length ];
for ( int i = 0; i < length; ++i ) {
result[ (length - i) - 1] = COMPLEMENT_TABLE_BYTES[ sequence[i] ];
}
return result;
}
public static String reverseComplement( String sequence ) {
byte[] complementBytes = reverseComplement(
sequence.getBytes( StandardCharsets.US_ASCII ));
return new String( complementBytes, StandardCharsets.US_ASCII );
}
使用您的示例序列:
public static void main(String[] args) {
String sequence = "ACGTA";
String complementSequence = complement( sequence );
System.out.println( String.format(
"complement(%s) = %s", sequence, complementSequence ));
String reverseComplementSequence = reverseComplement( sequence );
System.out.println( String.format(
"reverseComplement(%s) = %s", sequence, reverseComplementSequence ));
}
我们得到这个输出:
complement(ACGTA) = TGCAT
reverseComplement(ACGTA) = TACGT