如何使用字符串或字符向量(分别包含任何化学成分公式)并计算其摩尔质量?
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
。但是Fe
和N
没有。
在这一步之后,您的公式应更改为Fe1(N1O3)3
。
现在,将每个数字,例如上述公式的num
转换为:
*num+
如果当前数字后面有元素。
*num
如果你遇到')'或后面的公式结束。
在此之后,您的公式应更改为 Fe*1+(N*1+O*3)*3
。
现在,您的问题是解决上述公式。有一个非常简单的算法。请参考:https://www.geeksforgeeks.org/expression-evaluation/。在您的情况下,您的操作数可以是数字(比如2
)或元素(比如Fe
)。您的操作员可以是*
和+
。括号也可以出现。
要查找单个质量,您可以将包含 element name
的 std::map<std::string, int>
维护为 key
,并将其 mass
维护为 value
。
希望这会有所帮助。
【讨论】:
这与其说是一系列 cmets 的答案。答案应在要求的范围内具体回答问题。 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review @Andrew 我认为 OP 要求的是一个简单的算法。我认为它可以完成这项工作。您会看到标题并决定它是否完成这项工作。 @PasserBy 因为 OP 是初学者,我认为它相对更容易阅读而不是代码。不管你怎么做都应该传达这个想法。 @Andrew 如果您仍然认为此答案可以改进,请在此答案下方发布您的 cmets。我对此持开放态度。以上是关于如何使用字符串或字符向量(分别包含任何化学成分公式)并计算其摩尔质量?的主要内容,如果未能解决你的问题,请参考以下文章
怎样在word中快速输入复杂的公式(数学、物理或化学公式)?
如何找出字符串是不是包含在 std::vector 的任何字符串中?