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

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

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

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

Моей самой первой идеей было проверить все элементы (хранящиеся в символе вектора), шаг за шагом: если после заглавной буквы нет строчных букв, то я нашел, например, такой элемент, как углерод «C» вместо «Co» (кобальт) или «Cu» (медь). В основном я пытался использовать методы 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 Ответ

0 голосов
/ 27 января 2019

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

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

  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.

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

...