题目:计算分子量
纯净物都有一定的组成,可用一个相应的化学式来表示其组成成分。化学式是用元素符号表示物质组成及原子个数的式子。用化学符号表示物质分子的组成的化学式称为分子式,它的含义是:组成该化合物的元素,各元素原子数之比,各元素原子的重量之和。
化学式可以表示物质的1个分子,以及组成分子的元素种类和原子数量,如果要表示某物质的几个分子,可以在化学式前加上系数.标明该物质的分子数.如2个氧分子可用2O2表示,四氧化三铁可以用Fe3O4表示。
化学式的相对分子质量(简称分子量)是化学式中各原子的原子量的总和,即同种元素的相对原子质量与其原子个数相乘,不同原子的相对原子质量相加。例如:CO2, 碳是12, 氧是16, 那么,CO2分子量就是12+16×2=44 。
已知各化学分子式用到的元素原子量如下:
N | C | O | Cl | S | H | Al | Ca | Zn | Na |
14 | 12 | 16 | 35 | 32 | 2 | 27 | 40 | 65 | 23 |
计算各分子式的分子量。
【标准输入】
第一行: T 表示T个分子式。接下来有T行,每行是一个分子式。
【标准输出】
对于每个分子式,输出占一行,一个整数,即对应的分子量。
【约束条件】
2≤T≤8 ,化学式的长度不超过38
【 样 例 】
标准输入 | 标准输出 |
4 CO2 H2Na2SO4 N(NO2)3 (NH4)2SO4 | 44 146 152 140 |
要求:1:不带括号的分子式求解
2:带一层括号的分子式求解
进一步要求:带一层括号的分子式求解
#include<iostream>
#include<map>
#include<string>
#include<cstdio>
using namespace std;
map<string,int>mp;//保存原子的相对原子质量
int jisuan(string a)
{
map<string,int>mp_count;//保存所有原子的个数
int s=0;//保存结果
int len=a.length(),fenzishu=1;//保存分子数
if(isdigit(a[0]))//如果刚上来存在数字说明找到了这个分子的个数
{
fenzishu=a[0]-'0';
if(isdigit(a[1]))
fenzishu=fenzishu*10+a[1]-'0';
}
for(int i=0;i<len;i++)//开始遍历化学式
{
if(isupper(a[i]))//如果 遇到一个大写字母,说明发现一个新原子
{
string temp;//将这个新原子保存下来
temp=a[i];
int yuanzishu=1;//保存这个新原子的个数
if((i+1)<len&&isdigit(a[i+1]))//如果大写字母后面跟数字,说明找到了这个原子的个数
{
yuanzishu=a[i+1]-'0';
if((i+2)<len&&isdigit(a[i+2]))
yuanzishu=yuanzishu*10+a[i+2]-'0';
}
else if((i+1)<len&&islower(a[i+1]))//如果大写字母后面跟小写字母,将小写字母保存到元素名称中
{
temp+=a[i+1];
if((i+2)<len&&isdigit(a[i+2]))//如果大写字母后面跟小写字母再之后跟数字,说明找到了这个原子的个数
{
yuanzishu=a[i+2]-'0';
if((i+3)<len&&isdigit(a[i+3]))
yuanzishu=yuanzishu*10+a[i+3]-'0';
}
}
if(mp_count.count(temp)==0)//原子个数累加
mp_count[temp]=yuanzishu;
else
mp_count[temp]+=yuanzishu;
}
else if(a[i]=='(')//如果遇到括号,对括号里面的操作
{
string kuohao="";//保存括号里面的化学式
int n=1,k=i;
for(i=i+1;a[i]!=')';i++)
if(a[i]=='(')
n++;
for(i=k+1;n;i++)
{
if(a[i+1]==')')
n--;
kuohao+=a[i];
}
int fenzishu_kuohao=1;
if(isdigit(a[i+1]))
{
fenzishu_kuohao=a[i+1]-'0';
if(isdigit(a[i+2]))
fenzishu_kuohao=10*fenzishu_kuohao+a[i+2]-'0';
}
s+=jisuan(kuohao)*fenzishu_kuohao;//使用递归计算括号里面化学式的相对分子质量
}
}
int jieguo_kuohaowai=0;//保存括号外的相对分子质量
map<string,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++)
{
if(mp_count.count(it->first))//找出化学式中存在的元素
jieguo_kuohaowai+=mp[it->first]*mp_count[it->first];
}
s+=jieguo_kuohaowai*fenzishu;
return s;
}
int main()
{
mp["N"]=14;
mp["C"]=12;
mp["O"]=16;
mp["Cl"]=35;
mp["S"]=32;
mp["H"]=2;
mp["Al"]=27;
mp["Ca"]=40;
mp["Zn"]=65;
mp["Na"]=23;
int t;
cin>>t;
while(t--)
{
string a="";
cin>>a;
cout<<jisuan(a)<<endl;
}
getchar();getchar();
return 0;
}
注释
1.可实现多括号嵌套计算;
2.可实现下标为两位数字的计算;
3.可实现计算分子数;
测试样例:12Na12Al45(12S78(12Cl45H78(12H12)56)45)23结果为38898288
总结
1.map的基本操作函数:
C++ maps是一种关联式容器,包含“关键字/值”对
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数 (使用count,返回的是被查找元素的个数。如果有,返回1;否则,返回0。
注意,map中不存在相同元素,所以返回值只能是1或0。)
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素 (使用find,返回的是被查找元素的位置,没有则返回map.end()。)
get_allocator() 返回map的配置器
insert() 插入元素
2.isdigit是计算机C(C++)语言中的一个函数,主要用于检查其参数是否为十进制数字字符。(头文件<ctype.h>(C)<cctype>(C++) )
3.isupper是一个函数,可以用来判断字符c是否为大写英文字母。(头文件<ctype.h>(C)<cctype>(C++) )
4.islower,计算机函数,检查参数c是否为小写英文字母。(头文件<ctype.h>(C)<cctype>(C++) )