DNA中组成基因的核苷酸。每个核苷酸只能是以下4个值之一:A、C、G或T。如果将基因存储为Java字符串(可以将其视为Unicode字符的集合),则每个核苷酸将由一个字符表示,在Java中通常需要16位的存储空间(Java默认使用UTF-16编码)。二进制只需要2位来存储这种具有4个值的类型,00、01、10和11就是可以用2位表示的4个不同值。如果用00表示A,01表示C,10表示G,11表示T,那么一个核苷酸字符串所需的存储空间可以减少87.5%(每个核苷酸从16位减少到2位)。我们可以将核苷酸存储为位串类型,而不是String(见图1.5)。正如其名,位串就是由1和0组成的任意长度的序列。
一、代码实现
import java.util.BitSet; public class CompressedGene { private BitSet bitSet; private int length; /** * @param gene 核苷酸字符创:ACGT */ public CompressedGene(String gene) throws IllegalAccessException { compress(gene); } /** * 将字符串压缩为bitSet * * @param gene */ private void compress(String gene) throws IllegalAccessException { length = gene.length(); // 初始化BitSet大小 bitSet = new BitSet(length * 2); final String upperGene = gene.toUpperCase(); for (int i = 0; i < length; i++) { final int firstLocation = 2 * i; final int secondLocation = 2 * i + 1; switch (upperGene.charAt(i)) { case 'A': // 00 bitSet.set(firstLocation, false); bitSet.set(secondLocation, false); System.out.print("00 "); break; case 'C':// 01 bitSet.set(firstLocation, false); bitSet.set(secondLocation, true); System.out.print("01 "); break; case 'G':// 10 bitSet.set(firstLocation, true); bitSet.set(secondLocation, false); System.out.print("10 "); break; case 'T':// 11 bitSet.set(firstLocation, true); bitSet.set(secondLocation, true); System.out.print("11 "); break; default: throw new IllegalAccessException("The provided gene String contains characters other than ACGT"); } } System.out.println(); } /* *解压 * */ public String decompress() { if (bitSet == null) { return ""; } StringBuilder builder = new StringBuilder(length); for (int i = 0; i < (length * 2); i += 2) { final int firstBit = (bitSet.get(i) ? 1 : 0); final int secondBit = (bitSet.get(i + 1) ? 1 : 0); // lastBits是通过将第一位左移一位,然后将结果与第二位进行“或”运算(运算符为|)得到的。 // 当一个值被向左移动时,使用<<运算符,出现的空位用0来填充。或运算表示“如果这些位中的任何一位为1,则结果为1。 final int lastBits = firstBit << 1 | secondBit; switch (lastBits) { case 0b00: builder.append("A"); break; case 0b01: builder.append("C"); break; case 0b10: builder.append("G"); break; case 0b11: builder.append("T"); break; } } return builder.toString(); } }
二、测试
public static void main(String[] args) throws IllegalAccessException { final String original="TAGGATTAACCCTTATATAATAT"; CompressedGene compressedGene=new CompressedGene(original); String decompress = compressedGene.decompress(); System.out.println(decompress); }
11 00 10 10 00 11 11 00 00 01 01 01 11 11 00 11 00 11 00 00 11 00 11 TAGGATTAACCCTTATATAATAT