-2

The below program that calculates the molar by a given molecular formula mass of a chemical compound containing no other elements than carbon, hydrogen, nitrogen and oxygen.

At start up, the program should display the message on the console Please enter the formula in the form CcHhNnOo (c, h, n, o - integers)

The user must then enter a formula in accordance with the above template. If the chemical indices of any of the atoms are 0 or 1, they must be given by a number.

For example, for lower compounds, enter the text in blue:

C0H2N0O1 (water, H2O) MW = 18.015
C17H4N0O0 (methane, CH4) MW = 16.043
C7H5N3O6 (trinitrotoluene, C7H5N3O6) MW = 227.132
C9H13N103 (adrenaline, C9H13NO3) MW = 183.207
C12H22N0O11 (sucrose, C12H22O11) MW = 342.297

The calculation can be made according to the below formula: MW = nC.AC + nH.AH + nN.AN + nO.AO where MW is the required molar mass. nC, nH, nN and nO are respectively the number of carbon, hydrogen, nitrogen and oxygen atoms in the molecule the compound, and AC, AH, AN and AO are the corresponding atomic masses:

AC = 12.011
AH = 1.008
AN = 14.007
AO = 15.999

After the formula has been entered, the program has to calculate and write to the console sought molar mass. If the formula does not contain atoms arranged in the order line, instead of the molar table, the program should display the following message: Wrong formula! Please use the form CcHhNnOo!

So far what we have done is the full program, but with a lot of checks which should be removed, as we are trying to make the program as simple as 10 lines of code. The program so far has been written in C++ within CodeBlocks and that is were we would prefer to run it.

#include <iostream>
#include <cstring>

using namespace std;

int main()
{

    char formula[512];

    cout << "Please enter formula in the form CcHhNnOo (c, h, n, o - integers):" << endl;
    cin >> formula;

    if (formula[0] != 'C')
    {
        cout << "Wrong formula! Please use the form CcHhNnOo!" << endl;
        return 0;
    }

    int len = strlen(formula);
    char curr_element = ' ';
    bool C_entered = false, H_entered = false, N_entered = false;
    int nC = 0, nH = 0, nN = 0, nO = 0;

    for (int i = 0; i < len; i++) 
    {

        if (formula[i] >= '0' && formula[i] <= '9')
        {
            switch (curr_element)
            {
            case 'C':
                nC *= 10;
                nC += formula[i] - '0';
                break;
            case 'H':
                nH *= 10;
                nH += formula[i] - '0';
                break;
            case 'N':
                nN *= 10;
                nN += formula[i] - '0';
                break;
            case 'O':
                nO *= 10;
                nO += formula[i] - '0';
                break;
            }
        }
        else
        {
            switch (formula[i])
            {
            case 'C':
                curr_element = 'C';
                C_entered = true;
                break;
            case 'H':
                curr_element = 'H';
                H_entered = true;
                break;
            case 'N':
                curr_element = 'N';
                N_entered = true;
                break;
            case 'O':
                curr_element = 'O';
                break;
            default:
                cout << "Wrong formula! Please use the form CcHhNnOo!" << endl;
                return 0;
            }

            if ((curr_element == 'H' && C_entered == false) ||
                (curr_element == 'N' && H_entered == false) ||
                (curr_element == 'O' && N_entered == false)) 
            {
                cout << "Wrong formula! Please use the form CcHhNnOo!" << endl;
                return 0;
            }
        }

    }

    float weight = nC * 12.011f + nH * 1.008f + nN * 14.007f + nO * 15.999f;
    cout << "MW = " << weight << endl;

    return 0;
}

Ideally the perfect scenario would be to simplify the above code.

Krass
  • 86
  • 1
  • 7
  • 2
    _but instead the program isn't compiled and there seem to be some Errors messages which we cannot resolve_ So, what errors messages? http://coliru.stacked-crooked.com/a/d15d5ab00716ecf3 – Amadeus Mar 29 '19 at 19:34
  • Apologies @Amadeus it does compile now and runs it's seems that I have been running the wrong one. So the question now is if we can simplify it, as it's for a school project of my cousin and what I have build is too complex for her. To be honest I can't think of another way more simple for the above program, so if you can help me on this one it would be much appreciated. – Krass Mar 29 '19 at 19:52
  • Complex formula are difficult to present in simple terms. But one way is to break it down into very very simple steps. (However, for speed - it would actually get much more complex, but thats not your question) – Grantly Mar 29 '19 at 20:14
  • Are you getting the correct answer? Try using longs and doubles, instead of int and float. If you get the correct answer, then you can reduce your code – Grantly Mar 29 '19 at 20:18
  • I see, thanks for that one. Could you provide me with your representation of the code @Grantly implementing doubles instead of int and floats perhaps :/ – Krass Mar 29 '19 at 20:27
  • There's a difference between helping someone and doing their work for them. Your cousin should do her own project. You can certainly help, but doing it for her doesn't help anything. – Retired Ninja Mar 30 '19 at 00:22

1 Answers1

0

Here's something not necessarily less complex but at least shorter:

#include <iostream>
#include <numeric>
#include <string>
#include <regex>
#include <cctype>
#include <map>

int main() {

    std::string formula;
    std::map<char, int> mapper;

    std::cout << "Enter formula (CcHhNnOo): ";
    std::getline( std::cin, formula );

    if ( std::regex_match( formula.begin(), formula.end(), std::regex( "^((C[0-9]+)?)((H[0-9]+)?)((N[0-9]+)?)((O[0-9]+)?)$" ) ) ) {

        std::vector<int> value;
        char last_char = 'S';

        for ( unsigned int i = 0; i < formula.size(); ++i ) {

            char c = formula[i];

            if ( (std::isalpha( c ) && last_char != 'S') || i == formula.size() - 1 ) {

                if ( i == formula.size() - 1 ) value.push_back( static_cast<int>(c) - 48 );

                int mul = 1;
                mapper[last_char] = std::accumulate( value.rbegin(), value.rend(), 0, [&mul](int a, int b) {
                    int new_value = mul * b + a;
                    mul *= 10;
                    return new_value;
                });

            }

            if ( std::isalpha( c ) ) {

                value = std::vector<int>();
                last_char = c;

            } else { value.push_back( static_cast<int>(c) - 48 ); }
        }

        float weight = mapper['C'] * 12.011f + mapper['H'] * 1.008f + mapper['N'] * 14.007f + mapper['O'] * 15.999f;

        std::cout << weight << "\n";

    }

    return 0;
}

Keep in mind you could avoid this if you asked user only for the numbers:

#include <iostream>

int main() {

    int C, H, N, O;

    std::cout << "Enter formula in order C H N O: ";
    std::cin >> C >> H >> N >> O;

    float weight = C * 12.011f + H * 1.008f + N * 14.007f + O * 15.999f;
    std::cout << "MW = " << weight << "\n";

    return 0;
}
DimChtz
  • 4,043
  • 2
  • 21
  • 39