我正在尝试压缩基因组序列。这些是字母“A”“C”“G”和“T”的字符串。在文本文件形式中,它们存储为字符。由于它们只有4个,因此可以在文件中表示为两位。
换言之:ACTG - > 00 01 10 11,而不是8位字符
此数据将写回一个文件,其中每个字节代表4个字符。在bash脚本或C程序中执行此操作的最有效方法是什么?
谢谢!
答案 0 :(得分:2)
这是一个过滤器,它首先对最低有效位的序列进行编码:
#include <stdio.h>
int main(void) {
unsigned i = 0;
int c, d = 0;
while ((c = getchar()) != EOF) {
switch (c) {
case 'A': d |= 0 << (2 * (i & 3)); break;
case 'C': d |= 1 << (2 * (i & 3)); break;
case 'T': d |= 2 << (2 * (i & 3)); break;
case 'G': d |= 3 << (2 * (i & 3)); break;
default: continue; // ignore all other characters
}
if ((++i & 3) == 0) {
putchar(d);
d = 0;
}
}
if (i & 3) {
putchar(d);
}
return 0;
}
这里首先是最重要的位(也就是像素顺序)
#include <stdio.h>
int main(void) {
unsigned i = 0;
int c, d = 0;
while ((c = getchar()) != EOF) {
switch (c) {
case 'A': d = (d << 2) | 0; break;
case 'C': d = (d << 2) | 1; break;
case 'T': d = (d << 2) | 2; break;
case 'G': d = (d << 2) | 3; break;
default: continue; // ignore all other characters
}
if ((++i & 3) == 0) {
putchar(d);
d = 0;
}
}
if (i & 3) {
putchar(d << (2 * (3 - (i & 3))));
}
return 0;
}
注意:
序列用A
隐式填充,最多4个碱基。
将二进制数据写入stdout
可能会在stdout
处于文本模式的系统上产生不正确的输出,其语义与二进制模式不同(例如Windows,与OS / X或Unix不同) )。