計算分子量
題目:計算分子量
純淨物都有一定的組成,可用一個相應的化學式來表示其組成成分。化學式是用元素符號表示物質組成及原子個數的式子。用化學符號表示物質分子的組成的化學式稱為分子式,它的含義是:組成該化合物的元素,各元素原子數之比,各元素原子的重量之和。
化學式可以表示物質的1個分子,以及組成分子的元素種類和原子數量,如果要表示某物質的幾個分子,可以在化學式前加上係數.標明該物質的分子數.如2個
化學式的相對分子質量(簡稱分子量)是化學式中各原子的原子量的總和,即同種元素的相對原子質量與其原子個數相乘,不同原子的相對原子質量相加。例如: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++) )