3
void printEncodingCodonSequences (
            char aminoAcid1,
            char aminoAcid2,
            char aminoAcid3, 
            char aminoAcid4,
            char aminoAcid5
);

入力として 5 つのアミノ酸記号からなるタンパク質断片が与えられた場合、このタンパク質断片に翻訳されるすべての異なるコドン配列 (1 行に 1 つの配列) を (画面上に) 印刷します。入力はどのような場合でもかまいません。入力のいずれかが無効な場合、関数は「?」を出力する必要があります。一行で。

以下に例を示します。タンパク質フラグメント MWQWH は、これらの 4 つのコドン シーケンスによって翻訳できるため、入力用: 'M'、'W'、'Q'、'W'、'H' (または 'm'、' W'、'q'、'W'、'H')、関数は次のように出力する必要があります。

ATGTGGCAATGGCAT
ATGTGGCAGTGGCAT
ATGTGGCAATGGCAC
ATGTGGCAGTGGCAC

すべてに答えていただく必要はありません。やり方のヒントだけです。このタスクでは、文字列やコンテナ クラスは使用できません。配列でネストされたループを使用する必要があると言われました。

ここに画像の説明を入力

このプロジェクトでは、タンパク質フラグメントは 5 つのアミノ酸 (記号として入力) で構成されています。アミノ酸に複数のコドンがある場合、新しい行に出力されます。

4

3 に答える 3

1

これを実装するためにループを使用する必要があるという事実を考えると、これは5 つのネストされたループを使用してプログラムできます。各ループでは、1 つのアミノ酸記号の可能な翻訳コドン トリプレットをすべて調べます。それが基本的な考え方です。

次の疑似コードは、開始点として役立ちます。

for each translating codon triplet codon1 for aminoAcid1:
    for each translating codon triplet codon2 for aminoAcid2:
        for each translating codon triplet codon3 for aminoAcid3:
            for each translating codon triplet codon4 for aminoAcid4:
                for each translating codon triplet codon5 for aminoAcid5:
                    print codon1 + codon2 + codon3 + codon4 + codon5
                end for
            end for
        end for
    end for
end for

ここでやらなければならないことは、生の配列を使用して C++ でこれらのループを記述することです。アミノ酸記号ごとに、どのコドン トリプレット (およびいくつのコドン トリプレット) がループ内で通過しなければならない候補であるかが事前にわかっています。それらを定数配列として保存し、関数パラメーターから提供されたアミノ酸を使用して、ループ内でこの配列にアクセスします。

文字列とコンテナーを使用してはならないため、上記の表を C++ でエンコードするには、C 文字列 (char 配列) とその生の配列を使用する必要があります。疑似コード ( codon1... codon5)内の変数はconst char*(C-strings) である必要があり、 または のいずれcoutかを使用して出力できますprintf

上記のテーブルは、次のような配列として記述できます。あなたのテーブルのすべての行を、アミノ酸記号をエンコードする文字で始まり、その後にトリプレットの「リスト」が続く1つのC文字列として書いたことに注意してください. これらのトリプレットはすべて 0 で終了します (これにより、それらを C 文字列として指すことができます)。トリプレットを反復するには、null 終端文字を見つけて、このポインターを 1 つインクリメントするだけです。このポインターが null でない場合、別のトリプレットが来ます。null の場合 (これらの行の最後に、すべての文字列リテラルに追加されるときに別の null が追加されることに注意してください)、これが最後のトリプレットです。

const char *codons[] = {
    "AGCT\0GCC\0GCA\0GCG\0",
    "RCGT\0CGC\0CGA\0CGG\0AGA\0AGG\0",
    // ...
    "*TAA\0TGA\0TAG\0"
};

このテーブルから正しい行を見つけるユーティリティ関数を使用すると、ループは次のように記述できます (ここでは最初の酸記号)。

for(const char *codon1 = codonRow(aminoAcid1); codon1 += strlen(codon1); codon1 != NULL) {
    ...
}

このループでは、初期化でユーティリティ関数 (以下を参照) が使用され、テーブルから行が返されますが、最初の文字は除外されます (したがって、指定された酸の最初のコドン トリプレットを指します)。インクリメント操作は、このポインターを C 文字列の長さだけ増やします (これによりcodon1、次のヌル終了文字の直後を指すことになります)。これが null の場合、完了です。

良い点は、このループの各反復でcodon1C 文字列を指し (まあ、上記の配列の文字列リテラルのちょうど真ん中を指している)、適切に終了することです。したがって、印刷codon1すると3文字だけが印刷されます。

これは上記のループで使用されたユーティリティ関数で、テーブル内の特定の文字を検索して次の行を返します。

const char *codonRow(char aminoAcid)
{
    for(int i = 0; i < sizeof(codons)/sizeof(*codons); ++i) {
        const char *row = codons[i];   // Fetch the row from the array
        if (row[0] == aminoAcid)       // Compare the amino acid symbol
            return row + 1;            // Remove the amino acid symbol
    }
    // error:
    std::cerr << "No such amino acid: " << aminoAcid << std::endl;
    return 0;
}
于 2013-03-16T20:03:55.100 に答える
0

さて、あなたはアミノ酸配列をコドン配列に翻訳したいと考えています。したがって、最初に必要になるのは、アミノ酸コードをコドンに変換するための表です。クラスを使用することは許可されていないため、テーブルは配列を意味します。各アミノ酸は複数のコドンに翻訳される可能性があるため、配列の配列が必要です。

#define MAX_CODONS  6   /* maximum number of codons for one amino acid */
char *AminoAcidCodons[26][MAX_CODONS+1] = {
    /* A */ { "GCT", "GCC", "GCA", "GCT", 0 },
    /* B */ { 0 },
    /* C */ { "TGT", "TGC", 0 },
          :
    /* Y */ { "TAT", "TAC", 0 },
    /* Z */ { 0 },
};

これで、ループを使用して大文字をコドンのセットに変換できます。

for (i = 0; AminoAcidCodons[aminoAcid1 - 'A'][i]; i++) {
    /* AminoAcidCodons[aminoAcid1-'A'][i] is one of the codons that AminoAcid1 can be encoded as */
     :

5 つのアミノ酸のすべての可能な組み合わせを取得するには、5 つのネストされたループが必要です。小文字を扱うには、大文字に変換する必要があります。また、無効なコード (非文字および対応するコドンのない文字) に対処する必要があります。関数isalphatoupperここで役立ちます。

于 2013-03-16T20:13:24.600 に答える
0

わかりました、コドンが正確にいくつあるか言われたことは無視して、より一般的な解決策を説明します.

各コドンは正確に 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;
}

明らかに、他の多くのコドン マッピングを入力する必要があります。

于 2013-03-16T20:04:03.790 に答える