好的,我将忽略您被告知确切有多少密码子,并描述一个更通用的解决方案。
您知道每个密码子正好转换为 3 个字符,因此您可以预先计算所需缓冲区的大小。在您的情况下,您当然可以使用固定大小的缓冲区。请记住为终止 NUL 字符留出空间。此输出缓冲区将是一个数组。看起来像这样:
void printEncodingCodonSequences(
char aminoAcid1,
char aminoAcid2,
char aminoAcid3,
char aminoAcid4,
char aminoAcid5 )
{
char outputBuffer[16]; // 5 codons, exactly
char codons[] = { aminoAcid1, aminoAcid2, aminoAcid3, aminoAcid4, aminoAcid5 };
findCodonEncodingCombinations(outputBuffer, outputBuffer, codons, 5);
}
接下来,您需要将每个密码子映射到所有可能的序列,并针对给定的密码子重复此操作。因为这是一个组合问题,所以它非常适合递归。该函数采用第一个密码子,并遍历不同的可能编码。在每次迭代中,它会再次调用自己来处理剩余的密码子。
int findCodonEncodingCombinations( char* outputBuffer, char* outputPos, char* codons, int remaining )
{
if (remaining == 0) {
*outputPos = 0;
puts(outputBuffer);
puts("\n");
return 1;
}
int combinations = 0;
switch (*codon) {
case 'D': // GAT, GAC
case 'd':
outputPos[0] = 'G';
outputPos[1] = 'A';
outputPos[2] = 'T';
combinations += findCodonEncodingCombinations(outputBuffer, outputPos + 3, codons + 1, remaining - 1);
outputPos[2] = 'C';
combinations += findCodonEncodingCombinations(outputBuffer, outputPos + 3, codons + 1, remaining - 1);
break;
}
return combinations;
}
实际上,循环对于这个问题并不是特别有用。但是,您可以使用一个来验证所有输入是否有效,例如:
void printEncodingCodonSequences(
char aminoAcid1,
char aminoAcid2,
char aminoAcid3,
char aminoAcid4,
char aminoAcid5 )
{
char outputBuffer[16]; // 5 codons, exactly
char codons[] = { aminoAcid1, aminoAcid2, aminoAcid3, aminoAcid4, aminoAcid5 };
if (!validateCodons(codons, 5)) return;
findCodonEncodingCombinations(outputBuffer, outputBuffer, codons, 5);
}
bool validateCodons( char* codons, int count )
{
while (count--) { // it's a loop :)
switch (*codons++) {
case 'd':
case 'D':
//...
break;
default: // unrecognized codon
puts("?\n");
return false;
}
}
return true;
}
显然,您需要填写许多其他密码子映射。