Как использовать строку или символ-вектор (содержащий любой химический состав и соответственно формулу) и рассчитать его молярную массу?

Я пытаюсь написать простое консольное приложение на C++, которое может прочитать любую химическую формулу, а затем вычислить ее молярную массу, например:

  • Na2CO3 или что-то вроде:
  • La0,6Sr0,4CoO3 или в скобках:
  • Fe (NO3) 3

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

Моей самой первой идеей было проверить все элементы (хранящиеся в символе вектора), шаг за шагом: когда после заглавной буквы нет строчных букв, я нашел, например, такой элемент, как Carbon 'C' вместо "Co" (Cobalt). или "медь" (медь). В основном я пытался использовать методы isupper (...), islower (...) или isalpha (...).

// first idea, but it seems to be definitely the wrong way
// read input characters from char vector 
// check if element contains only one or two letters
// ... and convert them to a string, store them into a new vector
// ... finally, compute the molar mass elsewhere
// but how to deal with the numbers... ? 

for (unsigned int i = 0; i < char_vec.size()-1; i++)
{
    if (islower(char_vec[i]))
    {
        char arr[] = { char_vec[i - 1], char_vec[i] };
        string temp_arr(arr, sizeof(arr));
        element.push_back(temp_arr);
    }
    else if (isupper(char_vec[i]) && !islower(char_vec[i+1]))
    {
        char arrSec[] = { char_vec[i] };
        string temp_arrSec(arrSec, sizeof(arrSec));
        element.push_back(temp_arrSec);
    }
    else if (!isalpha(char_vec[i]) || char_vec[i] == '.')
    {
        char arrNum[] = { char_vec[i] };
        string temp_arrNum(arrNum, sizeof(arrNum));
        stoechiometr_num.push_back(temp_arrNum);
    }
}

Мне нужен простой алгоритм, который может работать с буквами и цифрами. Также может быть возможность работы с указателем, но в настоящее время я не очень знаком с этой техникой. В любом случае, я открыт для понимания, если кто-то захочет объяснить мне, как я могу использовать их здесь.

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

1 ответ

Эта проблема, конечно, не для начинающих, но я постараюсь дать вам некоторое представление о том, как вы можете это сделать.

Предположение: я не рассматриваю случай изотопов, в котором атомная масса может быть разной с одним и тем же атомным номером.

  1. Смоделируйте это с реальным миром.

    Как вы решите это в реальной жизни?

    Скажите, если я дам вам химическую формулу: Fe(NO3)3Что вы будете делать:

    1. Преобразуйте это во что-то вроде этого:

      Total Mass => [1 of Fe] + [3 of NO3] => [1 of Fe] + [ 3 of [1 of N + 3 of O ] ]
                 => 1 * Fe + 3 * (1 * N + 3 * O)
      
    2. Затем вы будете искать отдельные массы элементов, а затем заменить их.

      Total Mass => 1 * 56 + 3 * (1 * 14 + 3 * 16)
                 => 242
      
  2. Теперь перейдем к программированию.

    Поверьте мне, вы должны сделать то же самое в программировании.

    1. Преобразуйте свою химическую формулу в форму, описанную выше, т.е. Fe(NO3)3 в Fe*1+(N*1+O*3)*3, Я думаю, что это самая сложная часть в этой проблеме. Но это можно сделать и разбив на шаги.

      1. Проверьте, все ли элементы имеют номер после него. Если нет, то добавьте "1" после него. Например, в этом случае O имеет номер после него, который 3, Но Fe а также N не имеет его

      После этого шага ваша формула должна измениться на Fe1(N1O3)3,

      1. Теперь конвертируем каждое число, скажем num вышеуказанной формулы:

        1. *num+ Если после текущего номера есть какой-то элемент.

        2. *num Если вы встретили ')' или конец формулы после него.

        После этого ваша формула должна измениться на Fe*1+(N*1+O*3)*3,

    2. Теперь ваша задача - решить вышеприведенную формулу. Для этого есть очень простой алгоритм. Пожалуйста, обратитесь к: https://www.geeksforgeeks.org/expression-evaluation/. В вашем случае ваши операнды могут быть числом (скажем, 2) или элемент (скажем, Fe). Ваши операторы могут быть * а также +, Скобки также могут присутствовать.

Для нахождения отдельных масс, вы можете сохранить std::map<std::string, int> содержащий element name как key И его mass как value,

Надеюсь это немного поможет.

Другие вопросы по тегам