简单的数据压缩
压缩实际上就是一种节省空间的行为,比如一个字符占8位,当我们需要用一串字符来记录某种信息时,所占大小就是字符数x8.比如现在需要记录某一串遗传信息核苷酸ATCG。
eg:ATCGATTCTG
则需要10x8 = 80位。
因为以上的字符比较特殊,它是只有4个符号组成,那么我们约定:用2位存储来指代上面的其中一个符号,则就能达到节省空间的目的。
eg:A:00 T:01 C:10 G:11
那么上述字符串就能压缩成:00011011000101100111,只需要10x2=20位就能完成对该信息的存储。
这就是压缩原理。
需要解压缩的时候,再按每两位取出其中的值,通过枚举就能够解析原来存储的信息。当然这些压缩和解压缩需要事先进行设计的。
import Foundation
struct CompressedGene {
let lenght:Int
private let bitVector : CFMutableBitVector
init(string:String) {
lenght = string.count
bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault, lenght*2)
CFBitVectorSetCount(bitVector, lenght*2)
compress(gene: string)
}
private func compress(gene:String){
for (index,item) in gene.uppercased().enumerated() {
let start = index*2
switch item {
case "A":
CFBitVectorSetBitAtIndex(bitVector, start, 0)
CFBitVectorSetBitAtIndex(bitVector, start+1, 0)
case "T"://01
CFBitVectorSetBitAtIndex(bitVector, start, 0)
CFBitVectorSetBitAtIndex(bitVector, start+1, 1)
case "C"://10
CFBitVectorSetBitAtIndex(bitVector, start, 1)
CFBitVectorSetBitAtIndex(bitVector, start+1, 0)
case "G"://11
CFBitVectorSetBitAtIndex(bitVector, start, 1)
CFBitVectorSetBitAtIndex(bitVector, start+1, 1)
default:
print("混入了奇奇怪怪的东西,在第\(index)位")
}
}
}
}
print("\(CompressedGene(string: "ATCGATTCTG"))")
运行结果:
解压缩
private func decompress()->String{
var gene:String = ""
for index in 0 ..< lenght {
let start = index*2
let firstBit = CFBitVectorGetBitAtIndex(bitVector, start)
let nextBit = CFBitVectorGetBitAtIndex(bitVector, start+1)
switch (firstBit,nextBit) {
case (0,0):
gene += "A"
case (0,1):
gene += "T"
case (1,0):
gene += "C"
case (1,1):
gene += "G"
default:
break
}
}
return gene
}
|