如何使用字符串或字符向量(分别包含任何化学成分公式)并计算其摩尔质量?

Posted

技术标签:

【中文标题】如何使用字符串或字符向量(分别包含任何化学成分公式)并计算其摩尔质量?【英文标题】:How to use a string or a char vector (containing any chemical composition respectively formula) and calculate its molar mass? 【发布时间】:2019-01-27 00:30:23 【问题描述】:

我尝试用 C++ 编写一个简单的控制台应用程序,它可以读取任何化学公式,然后计算其摩尔质量,例如:

Na2CO3,或类似的东西: La0.6Sr0.4CoO3,或带括号: Fe(NO3)3

问题是我不详细知道如何处理输入流。我认为在这种情况下,读取输入并将其存储到 char 向量中可能比使用公共字符串更好。

我的第一个想法是逐步检查所有元素(存储在 char 向量中):当大写字母后没有小写字母时,我发现例如像碳“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);
    

我需要一个可以处理字母和数字的简单算法。也有可能使用指针,但目前我对这种技术不太熟悉。无论如何,我愿意接受这种理解,以防有人想向我解释我如何在这里使用它们。

我非常感谢任何支持,当然还有一些关于这个问题的代码 sn-ps,因为我想了很多天都没有进展……请记住,我是初学者而不是中级。

【问题讨论】:

c# Cut String at Capital Letter的可能重复 欢迎来到 Stack Overflow。这不是一个适合初学者的项目。如果你需要这个程序,我建议你请一个程序员为你编写它(也许在易货化学辅导中)。如果你真的想自己做,我建议你从更简单的练习开始,比如将不带括号的公式解析为其组成部分,如“CuO2”=> [Cu, O, 2]。这需要时间。 我不知道为什么这个问题会受到如此多的反对。它被清楚地说明并包含自己的工作尝试。因为你认为这个任务对初学者来说太难了,所以对一个问题投反对票是没有用的。特别是没有进一步解释。 @datell 你的推测为什么投反对票的人比反对票的人更能说明你。 @Florian C++14 或 17 是否可供您使用? 【参考方案1】:

这个问题肯定不适合初学者,但我会尝试给你一些关于如何做到这一点的想法。

假设:我没有考虑同位素的情况,即相同原子序数的原子质量可能不同。

    将其建模为现实世界。

    在现实生活中你将如何解决这个问题?

    说,如果我给你化学式:Fe(NO3)3,你会做的是:

      把它转换成这样的东西:

      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)
      

      然后,您将搜索大量元素,然后替换它们。

      Total Mass => 1 * 56 + 3 * (1 * 14 + 3 * 16)
                 => 242
      

    现在,开始编程吧。

    相信我,你在编程中也必须这样做。

      将您的化学式转换为上述形式,即将Fe(NO3)3 转换为Fe*1+(N*1+O*3)*3。我认为这是这个问题中最难的部分。但这也可以通过分解为步骤来完成。

        检查是否所有元素后面都有数字。如果不是,则在其后添加“1”。例如,在这种情况下,O 后面有一个数字,即3。但是FeN 没有。

      在这一步之后,您的公式应更改为Fe1(N1O3)3

        现在,将每个数字,例如上述公式的num 转换为:

          *num+如果当前数字后面有元素。

          *num如果你遇到')'或后面的公式结束。

        在此之后,您的公式应更改为 Fe*1+(N*1+O*3)*3

      现在,您的问题是解决上述公式。有一个非常简单的算法。请参考:https://www.geeksforgeeks.org/expression-evaluation/。在您的情况下,您的操作数可以是数字(比如2)或元素(比如Fe)。您的操作员可以是*+。括号也可以出现。

要查找单个质量,您可以将包含 element namestd::map&lt;std::string, int&gt; 维护为 key,并将其 mass 维护为 value

希望这会有所帮助。

【讨论】:

这与其说是一系列 cmets 的答案。答案应在要求的范围内具体回答问题。 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review @Andrew 我认为 OP 要求的是一个简单的算法。我认为它可以完成这项工作。您会看到标题并决定它是否完成这项工作。 @PasserBy 因为 OP 是初学者,我认为它相对更容易阅读而不是代码。不管你怎么做都应该传达这个想法。 @Andrew 如果您仍然认为此答案可以改进,请在此答案下方发布您的 cmets。我对此持开放态度。

以上是关于如何使用字符串或字符向量(分别包含任何化学成分公式)并计算其摩尔质量?的主要内容,如果未能解决你的问题,请参考以下文章

怎样在word中快速输入复杂的公式(数学、物理或化学公式)?

如何找出字符串是不是包含在 std::vector 的任何字符串中?

如何确定字符串是否包含在std :: vector的任何字符串中?

c++中字符串向量的索引[关闭]

Excel日期公式

如何从字符向量中解析 CSV 数据以提取数据框?