在字符串上循环并检查它是否只包含特定字符
loop over a string and check if it only contains specific characters
我试图遍历一系列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
for (int i =0; i <= seq.length(); i++)
应该是
for (int i =0; i < seq.length(); i++)
您正在读取seq[seq.length()]
,它是0,因此不是允许的字符之一,因此您的函数将始终返回false。
for (int i =0; i <= seq.length(); i++)
你在读字符串的大小。如果seq
的length()
为10,则其元素从[0]变为[9]。在循环中,您还访问了不属于字符串的元素[10],并且您的函数将返回false。将<=
更改为<
您可以执行以下操作:
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
的总大小。因此,条件CCD_。不需要使用
flag
变量。直接从该方法返回也可以。由于将
toUpper()
的结果存储回参数字符串只会更改本地副本,因此使用char
可以提高可读性。
如果你想要简单,std::string
提供了一些搜索功能。我不知道这是比其他解决方案快还是慢,但它确实有效。
bool isDNA(const std::string &seq) {
return seq.find_first_not_of("ATGCatgc") == std::string::npos;
}
我将在这里提供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:"样式循环(对像我这样不会计数的人来说很好;不需要逐个考虑(和auto(如果你不太关心类型(。
相关文章:
- C++-字符串是否包含一个带有简单循环的单词
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 检查一个数组是否包含在另一个数组中,以相反的顺序,至少两次
- 检查路径是否包含C++中的另一个路径
- C++17:使用 std::optional 来评估枚举是否包含值
- 如何检查 int 变量是否包含合法(非陷阱表示)值?
- 如何确定integer_sequence在编译时是否包含给定的数字?
- 使用预处理指令检查是否包含标头?
- 有没有办法搜索向量的元素,<String>然后检查它是否包含特定的字符,如果它确实打印了它
- 尝试使用 indexOf 创建一个 if 语句来检查字符串是否包含字符.有一点麻烦
- 如何检查字符串是否包含所有这些:数字、字母和特殊字符
- 在Rcpp(和RcppArmadillo)中,如何检查vec是否包含复数
- 使用按位运算确定值是否包含另一个值
- 如何检查一个字符串是否包含多个其他字符串?
- 如何检查联合是否包含类型(使用 type_traits)?
- Djinni 记录是否包含可选的接口字段
- 如何检查数组是否包含多个元素?
- 如何检查每个头文件是否包含必需的包含文件?
- 查找字符串是否包含字符串向量的任何一个元素的最佳方法
- 英特尔® IPP 异步 C/C++ 库是否包含在标准 IPP 库中?