循环一个字符串并检查它是否只包含特定字符

时间:2015-09-29 11:02:39

标签: c++

我试图遍历一串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

5 个答案:

答案 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;
    }
  1. 正如@interjay所述,您正在尝试访问seq[seq.length()],这是string总大小的一个。因此条件为i < seq.length()

  2. 无需使用flag变量。直接从该方法返回也可以解决问题。

  3. 由于将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:”样式循环(对于像我这样的人,不能计算;不需要考虑一个一个)和自动(如果你不这样)关注