«Как упростить программу для расчета молярной массы химического синтеза - PullRequest
0 голосов
/ 29 марта 2019

Приведенная ниже программа, которая вычисляет моляр по заданной молекулярной формуле масса химического соединения, не содержащего других элементов, кроме углерода, водород, азот и кислород.

При запуске программа должна отобразить сообщение на консоли Please enter the formula in the form CcHhNnOo (c, h, n, o - integers)

Затем пользователь должен ввести формулу в соответствии с приведенным выше шаблоном. Если химические индексы любого из атомов равны 0 или 1, они должны быть заданы числом.

Например, для низших соединений введите текст синим цветом:

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

Расчет можно сделать по приведенной ниже формуле: MW = nC.AC + nH.AH + nN.AN + nO.AO где МВт - требуемая молярная масса. nC, nH, nN and nO - соответственно число атомов углерода, водорода, азота и кислорода в молекуле соединение и AC, AH, AN and AO являются соответствующими атомными массами:

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

После ввода формулы программа должна вычислить и записать в консоль искала молярную массу. Если формула не содержит атомов, расположенных в строке заказа, вместо молярной таблицы, программа должна отобразить следующее сообщение: Wrong formula! Please use the form CcHhNnOo!

Пока что мы сделали полную программу, но с большим количеством проверок, которые должны быть удалены, поскольку мы пытаемся сделать программу такой же простой, как 10 строк кода. Программа до сих пор была написана на C ++ в CodeBlocks, и мы предпочли бы ее запустить.

#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;
}

В идеале идеальным сценарием было бы упростить приведенный выше код.

1 Ответ

0 голосов
/ 30 марта 2019

Вот что-то не обязательно менее сложное, но, по крайней мере, короче:

#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;
}

Имейте в виду, что этого можно избежать, если вы попросите пользователя только цифры:

#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;
}
...