使用BitSet对核苷酸数据压缩保存(减少87.5%空间)

简介: 使用BitSet对核苷酸数据压缩保存(减少87.5%空间)

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

相关文章
|
12月前
|
存储 Cloud Native Linux
C++ vector内存增长机制
C++ vector内存增长机制
|
存储 编译器 C语言
你知道数据在内存中是如何存储的嘛?(二)
你知道数据在内存中是如何存储的嘛?(二)
335 0
|
6月前
|
存储 缓存 数据安全/隐私保护
分段存储
分段存储
110 0
|
3月前
|
算法
时间(空间)复杂度(结构篇)
时间(空间)复杂度(结构篇)
38 6
|
5月前
|
人工智能 运维 Serverless
函数计算产品使用问题之上传模型文件占用的是什么空间
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
106 2
|
5月前
|
存储
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)
|
5月前
|
存储 缓存 算法
详解JVM内存优化技术:压缩指针
详解JVM内存优化技术:压缩指针
|
5月前
|
存储 NoSQL Redis
Redis第四弹,Redis实现list时候做出的优化ziplist(压缩链表,元素少的情况),可更好的节省空间list——(内部编码:quicklist)Object encoding
Redis第四弹,Redis实现list时候做出的优化ziplist(压缩链表,元素少的情况),可更好的节省空间list——(内部编码:quicklist)Object encoding
|
存储 编译器 C语言
数据的存储--深度解剖数据在内存中的存储(上)
数据的存储--深度解剖数据在内存中的存储(上)
|
算法 C# C++
1000多个文件,占用空间10G,删除的效率
1000多个文件,占用空间10G,删除的效率