我试图遍历一串DNA序列以检查序列是否是有效的DNA序列,我曾经使用python进行编码,但我现在正在尝试学习C ++,我找到了很多答案。问题但无法找到一个简单的问题。 我的问题是,如何循环一个字符串并检查它是否只包含一组有效字母?
这是使用python的相同功能:
#!/usr/bin/env python
def isDNA(seq):
seq = seq.upper()
flag = True
for base in seq:
if base not in ['A', 'T', 'G', 'C']:
flag = False
break
return flag
这是我第一次尝试使用C ++,尽管我认为它的逻辑是正确的,但它并不起作用!
#include<string>
#include<iostream>
using namespace std;
bool isDNA(string seq){
bool flag = true;
for (int i =0; i <= seq.length(); i++){
seq[i] = toupper(seq[i]);
if (seq[i]!='A' && seq[i]!= 'T' && seq[i] != 'G' && seq[i] !='C'){flag= false;break;}
}
return flag;
}
int main(){
string DNA1 = "ACGT";
string DNA2 = "acgt";
string DNA3 = "ATTF";
string DNA4 = "aafg";
cout << isDNA(DNA1)<<endl;
cout << isDNA(DNA2)<<endl;
cout << isDNA(DNA3)<<endl;
cout << isDNA(DNA4)<<endl;
return 0;
}
输出是0,0,0,0我应该是1,1,0,0
答案 0 :(得分:2)
for (int i =0; i <= seq.length(); i++)
应该是
for (int i =0; i < seq.length(); i++)
您正在阅读seq[seq.length()]
,即0,因此不是允许的字符之一,因此您的函数将始终返回false。
答案 1 :(得分:1)
for (int i =0; i <= seq.length(); i++)
您正在阅读字符串的大小。如果seq
的{{1}}为10,则其元素从[0]变为[9]。使用你的循环你也访问元素[10],它不是字符串的一部分,你的函数将返回false。将length()
更改为<=
答案 2 :(得分:1)
您可以执行以下操作:
bool isDNA(string seq){
for (int i =0; i < seq.length(); i++){
char c = toupper(seq[i]);
if (c !='A' && c != 'T' && c != 'G' && c !='C'){return false;}
}
return true;
}
正如@interjay所述,您正在尝试访问seq[seq.length()]
,这是string
总大小的一个。因此条件为i < seq.length()
。
无需使用flag
变量。直接从该方法返回也可以解决问题。
由于将toUpper()
的结果存储回参数字符串只会更改本地副本,而是使用char
来提高可读性。
答案 3 :(得分:1)
如果您想要简单,可以使用std::string
提供的搜索功能。我不知道这是否比其他解决方案更快或更慢,但确实有效。
bool isDNA(const std::string &seq) {
return seq.find_first_not_of("ATGCatgc") == std::string::npos;
}
答案 4 :(得分:1)
我将在这里提供Python版本的“翻译”。
#include <set>
#include <string>
//#include whatever toupper is from
bool isDNA(const std::string & candidate)
{
std::set<char> valid_chars = {'A', 'C', 'G', 'T'}; // "Initialization list", C++11 only I think
for (auto c : candidate) // C++ "for in", C++11 req'd
{
if(0 == valid_chars.count(toupper(c))) // will return 0 or 1
{
return false; // c isn't in valid_chars
}
}
return true;
}
虽然没有尽可能优化,但您可能会发现它更容易阅读。
还需要C ++ 11特别是“for:”样式循环(对于像我这样的人,不能计算;不需要考虑一个一个)和自动(如果你不这样)关注 。
。