Home > Mobile >  Why do i get two outputs?
Why do i get two outputs?

Time:04-11

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 ifs 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).

  •  Tags:  
  • c
  • Related