patterncppMinor
DNA base pair match counter
Viewed 0 times
matchdnacounterpairbase
Problem
So my code is done it outputs exactly what it needs to I'm just wondering if it is possible to make this code a lot more simple using objects. If so could someone tell me what I would need member-wise and I will try and implement it. When I tried it got way too complex and it ended up looking easier to just write functions and a whole ton of for loops with if statements.
The purpose of the code is to analyze 2 inputs (base and template) and then see if the template matches any chunks on the base. Also called Gattaca, but A goes to T, C goes to G, and vice versa.
Here is my code:
```
#include
#include
using namespace std;
bool AT(char a, char b) {
return ((a == 'A' && b == 'T') || (b == 'A' && a == 'T'));
}
bool CG(char a, char b) {
return ((a == 'C' && b == 'G') || (b == 'C' && a == 'G'));
}
bool match(char a, char b) {
return (AT(a, b) || CG(a, b));
}
int main() {
int case_count = 0;
string base;
string temp;
int base_size;
int temp_size;
int count;
cin >> case_count;
for (int i = 0; i > base;
cin >> temp;
base_size = base.size();
temp_size = temp.size();
if (base_size < temp_size) {
cout << "None";
continue;
}
if (base_size == temp_size) {
count = 0;
for (int index = 0; index < base_size; ++index) {
if (!(match(base[index], temp[index]))) {
cout << "None\n";
break;
}
else
count++;
}
if (count == temp_size) {
cout << "0\n";
}
continue;
}
for (int j = 0; j < base_size - (temp_size+1); ++j) {
count = 0;
for (int k = j; k < j + temp_size - 1; ++k) {
if (!(match(base[k], temp[count]))) {
break;
}
else
count++;
}
if (count == temp_size - 1) {
check = true;
cout << j << " ";
}
}
if (check == false) {
cout <<
The purpose of the code is to analyze 2 inputs (base and template) and then see if the template matches any chunks on the base. Also called Gattaca, but A goes to T, C goes to G, and vice versa.
Here is my code:
```
#include
#include
using namespace std;
bool AT(char a, char b) {
return ((a == 'A' && b == 'T') || (b == 'A' && a == 'T'));
}
bool CG(char a, char b) {
return ((a == 'C' && b == 'G') || (b == 'C' && a == 'G'));
}
bool match(char a, char b) {
return (AT(a, b) || CG(a, b));
}
int main() {
int case_count = 0;
string base;
string temp;
int base_size;
int temp_size;
int count;
cin >> case_count;
for (int i = 0; i > base;
cin >> temp;
base_size = base.size();
temp_size = temp.size();
if (base_size < temp_size) {
cout << "None";
continue;
}
if (base_size == temp_size) {
count = 0;
for (int index = 0; index < base_size; ++index) {
if (!(match(base[index], temp[index]))) {
cout << "None\n";
break;
}
else
count++;
}
if (count == temp_size) {
cout << "0\n";
}
continue;
}
for (int j = 0; j < base_size - (temp_size+1); ++j) {
count = 0;
for (int k = j; k < j + temp_size - 1; ++k) {
if (!(match(base[k], temp[count]))) {
break;
}
else
count++;
}
if (count == temp_size - 1) {
check = true;
cout << j << " ";
}
}
if (check == false) {
cout <<
Solution
It is extremely difficult to understand what's going on in your code. Try to think of things the following perspective: the goal of programming is to tell other people what you want the computer to do. And what you want to do is match the template to the base as some location. So how can we make that clearer?
Rather than character-wise matching for the appropriate inversion, we can just invert the template and then we just have to match for equality. Suppose we have a function:
which flips
We've now reduced dozens of lines of loops and variables, which are error prone, into a one line standard algorithm which is very easy to both reason about and for other users to understand. I don't know anything about chemistry, but I get this!
For minor comments, avoid
Rather than character-wise matching for the appropriate inversion, we can just invert the template and then we just have to match for equality. Suppose we have a function:
std::string invertDNA(std::string const& );which flips
A/T and C/G. Once we have that inversion, we're just searching for the inverted match_template in base:std::size_t index = base_template.find(invertDNA(match_template));
if (index == std::string::npos) {
std::cout << "None\n";
}
else {
std::cout << index << '\n';
}We've now reduced dozens of lines of loops and variables, which are error prone, into a one line standard algorithm which is very easy to both reason about and for other users to understand. I don't know anything about chemistry, but I get this!
For minor comments, avoid
using namespace std; and keep your indentation consistent. You do not need variables for the string length, since you can always call .size(). Avoid comparing against true and false. That part can be if (!check) { ... } else { ... }Code Snippets
std::string invertDNA(std::string const& );std::size_t index = base_template.find(invertDNA(match_template));
if (index == std::string::npos) {
std::cout << "None\n";
}
else {
std::cout << index << '\n';
}Context
StackExchange Code Review Q#109648, answer score: 2
Revisions (0)
No revisions yet.