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

#c #composition #chemistry

#c #состав #химия

Вопрос:

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

При запуске программа должна отображать сообщение на консоли 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
где MW — требуемая молярная масса. 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' amp;amp; 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' amp;amp; C_entered == false) ||
                (curr_element == 'N' amp;amp; H_entered == false) ||
                (curr_element == 'O' amp;amp; 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. но вместо этого программа не компилируется, и, похоже, появляются некоторые сообщения об ошибках, которые мы не можем разрешить Итак, какие сообщения об ошибках? coliru.stacked-crooked.com/a/d15d5ab00716ecf3

2. Извиняюсь @Amadeus, сейчас она компилируется и запускается, похоже, я запускал не ту. Итак, вопрос теперь в том, можем ли мы упростить это, поскольку это для школьного проекта моей двоюродной сестры, и то, что я собрал, слишком сложно для нее. Честно говоря, я не могу придумать другого способа, более простого для вышеупомянутой программы, поэтому, если вы можете помочь мне в этом, я был бы очень признателен.

3. Сложную формулу трудно представить в простых терминах. Но один из способов — разбить это на очень-очень простые шаги. (Однако, для скорости — это на самом деле стало бы намного сложнее, но это не ваш вопрос)

4. Вы получаете правильный ответ? Попробуйте использовать longs и doubles вместо int и float. Если вы получите правильный ответ, то сможете сократить свой код

5. Понятно, спасибо за это. Не могли бы вы предоставить мне свое представление кода @ Grantly, возможно, реализующего double вместо int и floats :/

Ответ №1:

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

 #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 ) amp;amp; 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, [amp;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;
}