0

I try to write a simple console application in C++ which can read any chemical formula and afterwards compute its molar mass, for example:

  • Na2CO3, or something like:
  • La0.6Sr0.4CoO3, or with brackets:
  • Fe(NO3)3

The problem is that I don't know in detail how I can deal with the input stream. I think that reading the input and storing it into a char vector may be in this case a better idea than utilizing a common string.

My very first idea was to check all elements (stored in a char vector), step by step: When there's no lowercase after a capital letter, then I have found e.g. an element like Carbon 'C' instead of "Co" (Cobalt) or "Cu" (Copper). Basically, I've tried with the methods isupper(...), islower(...) or 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);
    }
}

I need a simple algorithm which can handle with letters and numbers. There also may be the possibility working with pointer, but currently I am not so familiar with this technique. Anyway I am open to that understanding in case someone would like to explain to me how I could use them here.

I would highly appreciate any support and of course some code snippets concerning this problem, since I am thinking for many days about it without progress… Please keep in mind that I am rather a beginner than an intermediate.

Florian
  • 61
  • 5
  • Possible duplicate of [c# Cut String at Capital Letter](https://stackoverflow.com/questions/35268147/c-sharp-cut-string-at-capital-letter) – Tedinoz Jan 27 '19 at 00:45
  • 2
    Welcome to Stack Overflow. This is not a project for a beginner. If you need this program, I suggest you ask a programmer to write it for you (perhaps in barter for Chemistry tutoring). If you really want to do it yourself, I suggest you start with simpler exercises, like parsing a formula *without parentheses* into its components, like "CuO2" => [Cu, O, 2]. It will take time. – Beta Jan 27 '19 at 00:46
  • 2
    I don’t know why this question gets so many downvotes. It is clearly stated and contains an attempt of own work. Downvoting a question because you think the task is too hard for a beginner is just useless. In particular without further explanation. – dtell Jan 27 '19 at 01:59
  • 2
    @datell Your **speculation** about why the down voters downvoted says more about you than it says about the down voters. – Raedwald Jan 27 '19 at 09:46
  • @Florian Are C++14 or 17 available for you? – Hiroki Jan 29 '19 at 13:06
  • Dear all, first of all thank you very much for your replies. @Beta Well, it is not the case that I really need this program, it was just a purpose, my idea was to start a little project where I can learn more about coding performance at the same time. But as you have already mentioned, I myself have seen that this exercise may be a bit tricky for a beginner. – Florian Jan 31 '19 at 22:23
  • @Beta I think parsing a formula (without parentheses) into its components would not be a problem. Concerning the stoichiometric numbers and how to deal with them, it would look quite different. It reminds me oft he Stroustrup calculator, which works with a token and makes use of the concept of object oriented programming – for this time anyway, I found it a little confusing. – Florian Jan 31 '19 at 22:24
  • @Hiroki I have installed Microsoft Visual Studio (2017) with all needed packages a few weeks before, so I have assumed that my current operating C++-version would be the newest one. However, after checking by means of `__cplusplus`, I get C++98 as my standard version. – Florian Jan 31 '19 at 22:24
  • @Florian I think this would be helpful, https://stackoverflow.com/questions/41308933/how-to-enable-c17-compiling-in-visual-studio . – Hiroki Jan 31 '19 at 23:53

1 Answers1

-1

This problem is surely not for a beginner but I will try to give you some idea about how you can do that.

Assumption: I am not considering Isotopes case in which atomic mass can be different with same atomic number.

  1. Model it to real world.

    How will you solve that in real life?

    Say, if I give you Chemical formula: Fe(NO3)3, What you will do is:

    1. Convert this to something like this:

      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. Then, you will search for individual masses of elements and then substitute them.

      Total Mass => 1 * 56 + 3 * (1 * 14 + 3 * 16)
                 => 242
      
  2. Now, come to programming.

    Trust me, you have to do the same in programming also.

    1. Convert your chemical formula to the form discussed above i.e. Convert Fe(NO3)3 to Fe*1+(N*1+O*3)*3. I think this is the hardest part in this problem. But it can be done also by breaking down into steps.

      1. Check if all the elements have number after it. If not, then add "1" after it. For example, in this case, O has a number after it which is 3. But Fe and N doesn't have it.

      After this step, your formula should change to Fe1(N1O3)3.

      1. Now, Convert each number, say num of above formula to:

        1. *num+ If there is some element after current number.

        2. *num If you encountered ')' or end of formula after it.

        After this, your formula should change to Fe*1+(N*1+O*3)*3.

    2. Now, your problem is to solve the above formula. There is a very easy algorithm for this. Please refer to: https://www.geeksforgeeks.org/expression-evaluation/. In your case, your operands can be either a number (say 2) or an element (say Fe). Your operators can be * and +. Parentheses can also be present.

For finding individual masses, you may maintain a std::map<std::string, int> containing element name as key and its mass as value.

Hope this helps a bit.

Kunal Puri
  • 3,419
  • 1
  • 10
  • 22
  • 1
    This isn't so much an answer as a series of comments. Answers should, to the extent required, concretely answer the question. – Passer By Jan 27 '19 at 08:04
  • 1
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - [From Review](/review/low-quality-posts/22040299) – Andrew Jan 27 '19 at 09:17
  • @Andrew I think what OP asked for is a simple algorithm. And I think it does the job. You see the title and decide whether it does that job or not. – Kunal Puri Jan 27 '19 at 09:20
  • @PasserBy Because OP is a beginner, I think its relatively easier to read this rather than the code. The idea should be conveyed no matter how you do it. – Kunal Puri Jan 27 '19 at 09:21
  • @Andrew If you still think this answer can be improved, Please post your comments below this answer. I am open to it. – Kunal Puri Jan 27 '19 at 09:24
  • @PasserBy You can share your views as well. How can I improve this answer? – Kunal Puri Jan 27 '19 at 11:15
  • I did. You need a __concrete__ solution, not a series of hints. – Passer By Jan 27 '19 at 13:30
  • @Kunal Thank you very much for your proposal. Yeah, converting the formula into its compounds and stoichiometric values will be the hardest part. I will try these days and let you know if I succeeded. – Florian Jan 31 '19 at 22:25
  • @Florian I have updated my answer to make the **hardest** part a bit simple. Please check it out as well. – Kunal Puri Feb 01 '19 at 00:12