HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

DNA base pair match counter

Submitted by: @import:stackexchange-codereview··
0
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 <<

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:

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.