在C 中,我需要创建一个数组,其中包含字母“A”,“C”,“G”,“T”的每个可能的5个字母串组合。那是, AAAAA, AAAAG, AAAAC, 等等 我需要将这些存储在一个数组中。我知道有1024种可能的组合,因此数组将被分配。 我认为内存分配看起来像这样:
char* combinations[] = calloc(1024, 5*sizeof(char));
不确定如何用所有可能的组合填充这样的数组。
答案 0 :(得分:2)
以下代码可以满足您的需求。
#include <stdio.h>
#include <stdlib.h>
// type to encapsulate our 5 character long string
typedef char combination[5];
combination* getCombinations()
{
char letters[] = {'A','C','G','T'};
combination * combinations = (combination *)calloc(1024, sizeof(combination));
unsigned i;
unsigned int j;
for (i = 0; i < 1024; i++)
{
/*combinations[i] = &strings[i * 5];*/
for ( j = 5; j--;){
combinations[i][(4 - j)] = letters[(i >> (j * 2)) % 4]; //
}
}
return combinations;
}
int main()
{
int i;
combination * combinations = getCombinations();
for ( i = 0; i < 1024; i++){
printf("%.*s\n", 5, combinations[i]);
}
free(combinations);
}
重要的一行是内循环:
combinations[i][4 - j] = letters[(i >> (j * 2)) % 4];
此行的目的是通过简单计数将索引(0-1023)转换为组合。
让我们打破这个:
letters[... % 4]
根据任何内容(...
)返回一封信。 % 4
部分只需在1
,5
,9
,......全部返回'C'
(i >> (j * 2))
这基本上允许我们选择基础4
(可能的字母数)
combinations[i][4 - j]
将值设置为列表中j
字的i
字母(从右侧开始计算)。
答案 1 :(得分:1)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void f(char** out, int n, char* p)
{
if (n == 0) {
memcpy(*out, p - 5, 5);
*out += 5;
return;
}
for (int i = 0; i < 4; ++i) {
*p = "ACGT"[i];
f(out, n - 1, p + 1);
}
}
int main()
{
char* combinations = calloc(1024, 5);
char* comb = combinations;
char buf[5];
f(&comb, 5, buf);
for (int i = 0; i < 1024; ++i)
printf("%.5s\n", combinations + i * 5);
}