Поэтому я пытаюсь создать дополнение последовательности
TGAGACTTCAGGCTCCTGGGCAACGTGCTGGTCTGTGTGC
однако мой вывод не сработал, как ожидалось.
Дополнения для каждой буквы в последовательности:
A -> T
G -> C
C -> G
T -> A
Я программирую на Java уже более года, так что я немного разболтался с указателями на C ++, я предполагаю, что проблема заключается в обратных методах и пути к указателям смещаются при каждом проходе вызова функции.
#include<stdio.h>
#include<iostream>
using namespace std;
void reverse(char s[]);
int main() {
char s[40] = {'T','G','A','G','A','C','T','T','C','A','G','G','C','T','C','C','T','G','G','G','C','A','A','C','G','T','G','C','T','G','G','T','C','T','G','T','G','T','G'};
cout << "DNA sequence: "<< endl << s << endl;
reverse(s);
cout << "Reverse Compliment: "<< endl << s << endl;system("pause");
}
void reverse(char s[])
{
char c;
char *p, *q;
p = s;
if (!p)
return;
q = p + 1;
if (*q == '\0')
return;
c = *p;
reverse(q);
switch(c) {
case 'A':
*p = 'T';
break;
case 'G':
*p = 'C';
break;
case 'C':
*p = 'G';
break;
case 'T':
*p = 'A';
break;
}
while (*q != '\0') {
*p = *q;
p++;
q++;
}
*p = c;
return;
}
Стандартный современный C ++ делает это низкоуровневое, ориентированное на указатели программирование ненужным (фактически, вы фактически пишете C).
Как только у вас есть функция, скажем complement
, который превращает нуклеотид в его комплемент, вам просто нужно применить некоторые стандартные библиотечные функции, такие как transform
.
Вот переписать вашу программу на C ++ 11:
#include <string>
#include <iostream>
#include <algorithm>
#include <cassert>using namespace std;char complement(char n)
{
switch(n)
{
case 'A':
return 'T';
case 'T':
return 'A';
case 'G':
return 'C';
case 'C':
return 'G';
}
assert(false);
return ' ';
}int main()
{
string nucs = "ACAATTGGA";
transform(
begin(nucs),
end(nucs),
begin(nucs),
complement);
cout << nucs << endl;
}
Изменить reverse
такой метод
void reverse(char s[])
{
while (*s) {
switch(*s) {
case 'A':
*s = 'T';
break;
case 'G':
*s = 'C';
break;
case 'C':
*s = 'G';
break;
case 'T':
*s = 'A';
break;
}
++s;
}
return;
}
…и вы получите правильный результат.
Если вам не нравятся указатели, пожалуйста, не используйте их! В современном C ++ указатели не часто необходимы. Следующий код на C ++ 11 (у вас есть компилятор C ++ 11?) Написан так, как я бы это сделал.
#include <string>
#include <iostream>
#include <algorithm>
std::string reverse(std::string seq)
{
auto lambda = [](const char c) {
switch (c) {
case 'A':
return 'T';
case 'G':
return 'C';
case 'C':
return 'G';
case 'T':
return 'A';
default:
throw std::domain_error("Invalid nucleotide.");
}
};
std::transform(seq.cbegin(), seq.cend(), seq.begin(), lambda);
return seq;
}int main()
{
std::string seq("TGAGACTTCAGGCTCCTGGGCAACGTGCTGGTCTGTGTG");
std::cout << "DNA sequence: " << std::endl << seq << std::endl;
seq = reverse(seq);
std::cout << "Reverse Compliment: " << std::endl << seq << std::endl;
system("pause");
return EXIT_SUCCESS;
}
Некоторые заметки:
default
в switch
заявление.std::string
в простой символstd::string
стиль, выглядит легко и чисто: я предполагаю, что это может быть полезно для OP или других.
создание комплемента последовательности ДНК и ее обращение C ++
Другими словами, это обратный комплемент последовательности ДНК, что может быть легко достигнуто путем обращения последовательности ДНК с последующим получением ее комплемента. Или получить дополнение, а затем задним ходом. Пример показан ниже.
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string DNAseq = "TGAGACTTCAGGCTCCTGGGCAACGTGCTGGTCTGTGTGC";
reverse(DNAseq.begin(), DNAseq.end());
for (std::size_t i = 0; i < DNAseq.length(); ++i){
switch (DNAseq[i]){
case 'A':
DNAseq[i] = 'T';
break;
case 'C':
DNAseq[i] = 'G';
break;
case 'G':
DNAseq[i] = 'C';
break;
case 'T':
DNAseq[i] = 'A';
break;
}
}
std::cout << "reverse complement : " << DNAseq << std::endl;
return 0;
}