class ORF_Finder {
public:
void findORFs(string & strand, int sizeOfStrand);
vector<string> orf1Strands;
vector<string> orf2Strands;
vector<string> orf3Strands;
private:
string newStrand;
string newSub;
};
void ORF_Finder::findORFs(string & strand, int sizeOfStrand) {
int pos, pos1, index = 0;
for (int i = 0; i < strand.size(); i++) {
pos = strand.find("ATG");
pos1 = strand.find("TAA");
newSub = strand.substr(pos, pos1);
newStrand.insert(index, newSub);
strand.erase(pos, pos1);
index = index + 3;
if ((pos1 % 3 == 0) && (pos1 >= pos + 21)) {
orf1Strands.push_back(newStrand);
}
else if ((pos1 % 3 == 1) && (pos1 >= pos + 21)) {
orf2Strands.push_back(newStrand);
}
else if ((pos1 % 3 == 2) && (pos1 >= pos + 21)) {
orf3Strands.push_back(newStrand);
}
}
}
假设所有字符串都已声明,我正在“使用命名空间std”。
我的目标是向用户询问输入的DNA链(例如:“TCAATGCGCGCTACCATGCGGAGCTCTGGGCCCAAATTTCATCCATAACTGGGGCCCTTTTAAGGGCCCGGGAAATTT”)并查找子串以“ATG”开头并以“TAA”,“TAG”或“TGA”结尾的所有实例(为简单起见,我省略了“TAG”和“TGA”。
子串将如此:“ATG ...... ...... ...... TAA”然后它将被存储到一个矢量中以便以后使用。但是,我想找到每个阅读框的多个实例(ORF1应该从进口链的“T”开始,ORF2应该从进口链的“C”开始,ORF3应该从“A”开始。导入的链)并且应该在三元组中工作,因此在if语句中包含mod 3。 “pos1&gt; = pos + 21”的目的是使每个子串长至少七个密码子。
上面的代码是我迄今为止所做的,但显然,这是不正确的。我试图告诉pos找到“ATG”和pos1找到“TAA”。 newSub是将从“ATG”生成到“TAA”的子字符串,并且将生成newStrand以包含子字符串。然后我会删除链的一部分(以避免重复)和增加索引。
对于长篇描述感到抱歉,但我一直在强调这一点,我已经尽力解决这个问题。
答案 0 :(得分:1)
Knutt-Morris Pratt是最快的解决方案。 Aho-corasick算法是一种来自kmp算法的广义版本。基本上它是一个带有从广度优先搜索计算的失败链接的特里。您可以尝试我的PHP实现phpahocorasick @ codeplex.com。然后,您需要添加通配符以查找所有子字符串。
答案 1 :(得分:0)
简单:
您将拥有一些角落,例如:处理可以不同配对的多个信号序列,但这些只是正常的编程。
您的方法存在的问题是您不是从头到尾扫描字符串,而是从头开始重复搜索开头和结尾。你需要在最后一个位置后继续。查看string
类的各种{{1}}函数,了解如何执行此操作。
答案 2 :(得分:0)
这是一种可能的实施方式。
特点:
代码:
#include <iostream>
#include <string>
#include <stdexcept>
#include <vector>
class Strand {
const std::string* data;
size_t begin;
size_t len;
public:
Strand(const std::string& data, size_t begin, size_t end): begin(begin),
len(end - begin), data(&data) {
if (end <= begin) {
throw std::invalid_argument("end < begin");
}
}
std::string getString() const {
const char *beg = data->c_str();
beg += begin;
return std::string(beg, len);
}
};
class Parser {
const std::string& data;
const std::string& first;
const std::vector<std::string>& end;
size_t dataLen;
std::vector<Strand> orf1Strands;
std::vector<Strand> orf2Strands;
std::vector<Strand> orf3Strands;
public:
enum TypStrand {
one = 0, two, three
};
Parser(const std::string& data, const std::string& first,
const std::vector<std::string>& end): data(data),
first(first), end(end) {
dataLen = data.length();
}
void parse();
const std::vector<Strand>& getVector(int typ) const {
switch(typ) {
case 0 : return orf1Strands;
case 1 : return orf2Strands;
default : return orf3Strands;
}
}
const std::vector<Strand>& getVector(TypStrand typ) const {
return getVector((int) typ);
}
};
void Parser::parse() {
size_t pos=0;
size_t endSize = end.size();
std::string firstChars = "";
for(size_t i=0; i<endSize; i++) {
firstChars += end[i].at(0);
}
for(;;) {
pos = data.find(first, pos);
if (pos == std::string::npos) break;
size_t strandEnd = pos + 18;
for(;;) {
if (strandEnd + 3 >= dataLen) break;
strandEnd = data.find_first_of(firstChars, strandEnd);
if ((strandEnd - pos) % 3 != 0) {
strandEnd += 1;
continue;
}
if (strandEnd + 3 >= dataLen) break;
for (size_t i=0; i<endSize; i++) {
if (data.compare(strandEnd, end[i].length(), end[i]) == 0) {
std::cout << "Found sequence ended with " << end[i] << std::endl;
switch(pos %3) {
case 0 :
orf1Strands.push_back(Strand(data, pos,
strandEnd + 3));
break;
case 1 :
orf2Strands.push_back(Strand(data, pos,
strandEnd + 3));
break;
case 2 :
orf3Strands.push_back(Strand(data, pos,
strandEnd + 3));
break;
}
pos = strandEnd + end[i].length() - 1;
break;
}
}
if (pos > strandEnd) break;
strandEnd += 3;
}
if (strandEnd + 3 >= dataLen) break;
pos = pos + 1;
}
}
using namespace std;
int main() {
std::string first = "ATG";
vector<string> end;
std::string ends[] = { "TAA", "TAG", "TGA"};
for (int i=0; i< sizeof(ends)/sizeof(std::string); i++) {
end.push_back(ends[i]);
}
string data = "TCAATGCGCGCTACCATGCGGAGCTCTGGGCCCAAATTTC"
"ATCCATAACTGGGGCCCTTTTAAGGGCCCGGGAAATTT";
Parser parser(data, first, end);
parser.parse();
for (int i=0; i<3; i++) {
int typ = i;
const vector<Strand>& vect = parser.getVector(typ);
cout << "Order " << i << " : " << vect.size() << endl;
if (vect.size() > 0) {
for(size_t j=0; j<vect.size(); j++) {
cout << vect[i].getString() << endl;
}
}
}
return 0;
}
Todo: