I've been writing this code for my biology class and it worked pretty much without any error but then i noticed it sometimes gives two outputs instead of one. (For example "Ile Met " instead of "Met") Also i know my code is a mess so can you please help by that too, which parts and how should i change?
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
string sdna;
cout << "Enter codogener strang: ";
cin >> sdna;
int n = sdna.size();
char dna[100];
char mrna[100];
strcpy_s(dna, sdna.c_str());
cout << "DNA: ";
for (int i = 0; i < n; i ) {
cout << dna[i];
if (i % 3 == 2)
cout << " ";
}
for (int i = 0; i < n; i )
{
if (dna[i] == 'A')
mrna[i] = 'U';
else if (dna[i] == 'T')
mrna[i] = 'A';
else if (dna[i] == 'G')
mrna[i] = 'C';
else if (dna[i] == 'C')
mrna[i] = 'G';
}
cout << "\nmRNA: ";
for (int i = 0; i < n; i )
{
cout << mrna[i];
if (i % 3 == 2)
cout << " ";
}
cout << "\n";
for (int k = 0; k < n; k ) {
if ((mrna[k * 3] == 'A') && (mrna[k * 3 1] == 'U') && (mrna[k * 3 2] == 'U' || 'C' || 'A'))
cout << "Ile ";
if ((mrna[k * 3] == 'A') && (mrna[k * 3 1] == 'U') && (mrna[k * 3 2] == 'G'))
cout << "Met ";
if ((mrna[k * 3] == 'A') && (mrna[k * 3 1] == 'C') && (mrna[k * 3 2] == 'U' || 'C' || 'A' || 'G'))
cout << "Thr ";
if ((mrna[k * 3] == 'A') && (mrna[k * 3 1] == 'A') && (mrna[k * 3 2] == 'U' || 'C'))
cout << "Asn ";
if ((mrna[k * 3] == 'A') && (mrna[k * 3 1] == 'A') && (mrna[k * 3 2] == 'G' || 'A'))
cout << "Lys ";
if ((mrna[k * 3] == 'A') && (mrna[k * 3 1] == 'G') && (mrna[k * 3 2] == 'U' || 'C'))
cout << "Ser ";
if ((mrna[k * 3] == 'A') && (mrna[k * 3 1] == 'G') && (mrna[k * 3 2] == 'G' || 'A'))
cout << "Arg ";
if ((mrna[k * 3] == 'G') && (mrna[k * 3 1] == 'U') && (mrna[k * 3 2] == 'U' || 'C' || 'A' || 'G'))
cout << "Val ";
if ((mrna[k * 3] == 'G') && (mrna[k * 3 1] == 'C') && (mrna[k * 3 2] == 'U' || 'C' || 'A' || 'G'))
cout << "Ala ";
if ((mrna[k * 3] == 'G') && (mrna[k * 3 1] == 'A') && (mrna[k * 3 2] == 'U' || 'C'))
cout << "Asp ";
if ((mrna[k * 3] == 'G') && (mrna[k * 3 1] == 'A') && (mrna[k * 3 2] == 'A' || 'G'))
cout << "Glu ";
if ((mrna[k * 3] == 'G') && (mrna[k * 3 1] == 'G') && (mrna[k * 3 2] == 'U' || 'C' || 'A' || 'G'))
cout << "Gly ";
if ((mrna[k * 3] == 'U') && (mrna[k * 3 1] == 'U') && (mrna[k * 3 2] == 'U' || 'C'))
cout << "Phe ";
if ((mrna[k * 3] == 'U') && (mrna[k * 3 1] == 'U') && (mrna[k * 3 2] == 'A' || 'G'))
cout << "Leu ";
if ((mrna[k * 3] == 'U') && (mrna[k * 3 1] == 'C') && (mrna[k * 3 2] == 'U' || 'C' || 'A' || 'G'))
cout << "Ser ";
if ((mrna[k * 3] == 'U') && (mrna[k * 3 1] == 'A') && (mrna[k * 3 2] == 'A' || 'G')) {
cout << "Stopp ";
return 0;
}
if ((mrna[k * 3] == 'U') && (mrna[k * 3 1] == 'A') && (mrna[k * 3 2] == 'U' || 'C'))
cout << "Tyr ";
if ((mrna[k * 3] == 'U') && (mrna[k * 3 1] == 'G') && (mrna[k * 3 2] == 'A')) {
cout << "Stopp ";
return 0;
if ((mrna[k * 3] == 'U') && (mrna[k * 3 1] == 'G') && (mrna[k * 3 2] == 'U' || 'C'))
cout << "Cys ";
}
if ((mrna[k * 3] == 'U') && (mrna[k * 3 1] == 'G') && (mrna[k * 3 2] == 'G'))
cout << "Trp ";
if ((mrna[k * 3] == 'C') && (mrna[k * 3 1] == 'U') && (mrna[k * 3 2] == 'U' || 'C' || 'A' || 'G'))
cout << "Leu ";
if ((mrna[k * 3] == 'C') && (mrna[k * 3 1] == 'C') && (mrna[k * 3 2] == 'U' || 'C' || 'A' || 'G'))
cout << "Pro ";
if ((mrna[k * 3] == 'C') && (mrna[k * 3 1] == 'A') && (mrna[k * 3 2] == 'U' || 'C'))
cout << "His ";
if ((mrna[k * 3] == 'C') && (mrna[k * 3 1] == 'A') && (mrna[k * 3 2] == 'A' || 'G'))
cout << "Gln ";
if ((mrna[k * 3] == 'C') && (mrna[k * 3 1] == 'G') && (mrna[k * 3 2] == 'U' || 'C' || 'A' || 'G'))
cout << "Arg ";
}
return 0;
}
CodePudding user response:
I am suspicious of all of your conditions of the form mrna[k * 3 2] == 'U' || 'C' || 'A'
. That doesn't check mrna[k * 3 2]
against any of the three letters, it is unconditionally true
.
I would also advise against using char [100]
. You are already reading into a std::string
, that also has operator[]
, and it also has operator==
.
You are also (potentially) indexing past the end of your data. Your loop condition is k < n
, where n is the "length" of mrna
, but you index mrna[k * 3]
. Either change the condition, or change how you index.
But what I would most suggest is to replace the long string of if
s with a std::map
, which you can populate for each triple.
#include <iostream>
#include <string>
#include <map>
void print_triple(const std::string & s)
{
for (int i = 0; i < s.size(); i ) {
std::cout << s[i];
if (i % 3 == 2)
std::cout << " ";
}
}
static std::map<std::string, std::string> mrna_lookup
{
{ "AUU", "Ile " },
{ "AUC", "Ile " },
{ "AUA", "Ile " },
{ "AUG", "Met " },
// etc
};
int main()
{
std::string dna;
std::cout << "Enter codogener strang: ";
std::cin >> dna;
std::cout << "DNA: ";
print_triple(dna);
std::string mrna;
for (char c : dna)
{
switch (c)
{
case 'A': mrna.push_back('U'); break;
case 'T': mrna.push_back('A'); break;
case 'G': mrna.push_back('C'); break;
case 'C': mrna.push_back('G'); break;
}
}
cout << "\nmRNA: ";
print_triple(mrna);
cout << "\n";
std::string_view mrna_view = mrna; // view so .substr doesn't copy
for (int k = 0; k 2 < mrna.size(); k = 3)
{
auto it = mrna_lookup.find(mrna_view.substr(k, 3));
if (it != mrna_lookup.end())
{
std::cout << it->second;
if (it->second == "Stopp ")
{
return 0;
}
}
}
return 0;
}
CodePudding user response:
Your bug is (mrna[k * 3 2] == 'U' || 'C' || 'A')
.
You probably thought that this checks whether mrna[k * 3 2]
is equal to either U
, C
or A
. But that's not what it does... The ||
("or") operators combines three conditions - one of them is mrna[k * 3 2] == 'U'
, as you expected, but the other two are 'C'
and 'A'
. The C/C language treats these character constants as unconditionally true (because they are numbers not equal zero), so the entire expression is unconditionally true.
The correct code would be (mrna[k * 3 2] == 'U' || mrna[k * 3 2] == 'C' || mrna[k * 3 2] == 'A')
.
You can save mrna[k * 3 2
] in a variable with a shorter name to make these expressions shorter, and also faster (however, modern optimizers will do this optimization for you automatically, even if you don't do it explicitly).