c - C: 将 DNA 序列压缩成二进制
问题描述
嗨,我试图弄清楚如何获得将 DNA 代码转换为二进制位的函数,需要使它看起来像这样:ACGTT -> XXXXXX11 11100100 从右到左 for A=0 C=1 G=2 T=3 . 现在我想按字符来做,然后将它移出函数>>2,但我无法弄清楚函数本身......我试过这样,这样它就返回NULL。
char CompressChar(char c){
char temp[8]="XXXXXXXX";
if (c=='A'){
temp[7] = '0';
temp[6] = '0';
}
if (c=='C'){
temp[7]='1';
temp[6]='0';
}
if(c=='G'){
temp[7]='0';
temp[6]='1';
}
if(c=='T'){
temp[7]='1';
temp[6]='1';
}
return temp;
}
解决方案
我认为您希望每个字母(它们称为核苷酸 iirc?)代表 2 个二进制数字。
首先,char temp[8]="XXXXXXXX";
没有意义,因为 C 中的字符串是空终止的,并且您没有为空终止符分配空间,应该是[8+1]
. 你想要 16 位,而不是 8 位。
您的函数返回char
不正确的,您需要返回整个数组。这必须通过参数来完成,因为您不能在 C 中返回数组。不能返回指向本地数据的指针,因此将分配留给调用者会更好。无论如何...刮掉那个功能。
此外,将其转换为“二进制字符串”也没有多大意义。最好将其转换为二进制数,然后根据需要将该数转换为字符串。
转换,包括“倒序”,可以这样完成:
uint16_t dna_to_bin (const char* str)
{
uint16_t result = 0;
size_t i;
for(i=0; i<16; i+=2) // loop over bits in the resulting binary number
{
typedef enum // local enum just for readability
{
A = 0,
C = 1,
G = 2,
T = 3,
} dna_t;
dna_t type=0; // default is 0 if nothing to decode
if(*str != '\0') // keep decoding string until reaching the end
{
switch(*str)
{
case 'A': type = A; break;
case 'C': type = C; break;
case 'G': type = G; break;
case 'T': type = T; break;
}
str++;
}
result |= (uint16_t)type << i; // store data at correct position in the result
}
return result;
}
完整示例,包括打印二进制并丢弃下面的前导零的函数。如果你想用 X 替换前导零,修改应该很简单。
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdbool.h>
uint16_t dna_to_bin (const char* str)
{
uint16_t result = 0;
size_t i;
for(i=0; i<16; i+=2)
{
typedef enum
{
A = 0,
C = 1,
G = 2,
T = 3,
} dna_t;
dna_t type=0;
if(*str != '\0')
{
switch(*str)
{
case 'A': type = A; break;
case 'C': type = C; break;
case 'G': type = G; break;
case 'T': type = T; break;
}
str++;
}
result |= (uint16_t)type << i;
}
return result;
}
void print_bin (uint16_t bin)
{
bool remove_zeroes = true;
for(size_t i=0; i<16; i++)
{
uint16_t mask = 1u << (16-1-i);
uint16_t bit = bin & mask;
if(bit == 0)
{
if(!remove_zeroes)
{
printf("0");
}
}
else
{
remove_zeroes = false;
printf("1");
}
}
}
int main (void)
{
const char STR_DNA[] = "ACGTT";
uint16_t bin = dna_to_bin(STR_DNA);
puts(STR_DNA);
printf("Hex: %.4"PRIX16 "\n", bin);
printf("Bin: ");
print_bin(bin);
return (0);
}
输出:
ACGTT
Hex: 03E4
Bin: 1111100100
推荐阅读
- c# - 如何通过字符串分隔符读取潜在的大文件,对其进行处理并将其保存到不同的文件中?
- html - 如何修复苹果设备的 flexbox 示例?
- liferay - Liferay:向导设置后字段丢失?
- prolog - 简单解释一下 Prolog 程序是如何工作的?考虑下面给出的 Prolog 程序
- python - 如何在没有 NaN 的情况下组合 groupby 结果?
- python - ImportError:没有名为“django”的模块 uWSGI Django Nginx Ubuntu 16.04 Python3.6
- c# - WPF 添加生成内容的最佳方式
- angular - 角度材料自动完成 - 如何防止键盘输入以选择建议面板中的选项
- angular - mat-checkbox 在更新 firestore / reload 页面后继续选择
- python - 为什么在我的数据中调用转置会将行的索引从 MultiIndex 切换到平面索引?