计算分子量

题目:计算分子量                   

纯净物都有一定的组成,可用一个相应的化学式来表示其组成成分。化学式是用元素符号表示物质组成及原子个数的式子。用化学符号表示物质分子的组成的化学式称为分子式,它的含义是:组成该化合物的元素,各元素原子数之比,各元素原子的重量之和。

化学式可以表示物质的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++) )

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Since 6.0.0 6.6.0 + 增加由精确分子量搜索分子式小工具(在“工具”菜单中选择) * 改进最简式结果,现在总是把碳(C)元素放在最前,其余原子按原子序数排列 * 界面上一些细节的改进 - 为适应 Window 7 及后续版本,本程序最小化后不再在任务栏隐藏,直接点击主窗口上的关闭按钮将直接退出程序 - 去掉了精简模式窗口 - 去掉了窗口“总在前面”选项 6.5.0 + 内置所有天然同位素精确质量,用户指定某种同位素的质量数时,如果恰好是天然同位素,则用内置的精确同位素质量代替用户输入的质量数(仅当原子量使用“精确值”或“最高丰度精确值”时有效)。比如如果输入{13C},则使用原子量13.0034(之前的版本直接使用13.0000) + 内置一个计算不饱和度的小工具(工具-->计算不饱和度) + 增加一个独立运行的分子式格式化工具,可以将剪贴板中的文字按一般分子式的要求将数字变成上下标 * 用户指定某种同位素时,可以不指定质量数,程序将根据“使用原子量”选项选用最高丰度的同位素的精确质量或者质量数进行计算。比如输入{H},程序将选用原子量1.0078进行计算(之前的版本将报错) * 改进了最简式结果,现在总是把碳(C)元素放在最前,氧(O)元素放在最后,更符合一般人的阅读习惯 * 大量程序界面细节的改进,现在可以在各种列表和表格中正常显示分子式,不再需要安装任何字体文件,速度也更快 * 批量计算部分重写,现在这个功能有了界面 * 主菜单上一些功能增加了快捷键,程序中个别快捷键修改 * 程序全面支持UNICODE - RTF格式历史记录合并到“历史记录”中,原RTF格式历史记录选项不再有效 - 修正一个前端显示时主窗口可能遮住对话窗口的BUG 6.4.1 + 增加批量计算功能,在“工具”菜单中,一些过长的分子式可以从文件中导入防止显示速度过慢 - 修正一处同位素质量数显示问题 - 修正统计基团时潜在的问题 * 改进历史记录存盘文件样式 6.4.0 + 增加一个选项,可以选择不即时给出结果,以加快输入速度 - 修正在输入很长分子式时光标移出输入框的问题 * 改写内核,大幅提高大小写自动判断速度,尤其含有大量缩写时 * 改写内核,提高计算速度 * 将氨基酸缩写改为更简洁形式,提高计算速度 * 一些细节的优化,提高效率 6.3.0 + 缩写设定中缩写值首字母为"_"(英文下划线)时将忽略此项 + 默认设定下加入20种氨基酸残基的缩写(每种去掉一分子水) - 修正某对话框中的错别字 - 修正缩写设定对话框中不能输入"="的问题 - 修正缩写设定中缩写为空时造成的程序错误 - 修正安装后在C盘根目录下留下CHEM_4.TTF文件的问题 - 修正卸载后不能删除快速启动栏快捷方式的问题 * 增强监视剪贴板的兼容性:自动忽略复制到剪贴板中的分子式中前后的空格 * 缩写设定对话框和原子量设定对话框中按ESC可以直接关闭 6.2.2 - 修正某些情况下重复运行程序窗口不能弹出的问题 - 修正有时程序退出时会弹出调试对话框的问题 6.2.1: - 修正窗口隐藏时检测到剪贴板变化不能弹出的问题 6.2.0: + 增加两个选项:是否启用历史记录功能,如果禁用,可以加快计算速度,默认开启 + 增加设置窗口的快捷键为F10 + 自定义原子量窗口增加快速功能 + 增加展开缩写的功能,在编辑菜单中 - 修正输入分子式长度有限制的bug * 程序界面细小改进:在关于窗口点击版本号弹出ChangeLog * 程序细节的改进 6.1.1: + 增加分子量计算器主页 - 修正分子式括号中角标显示不正确的问题 * 程序细节的改进 6.1.0: + 增加一套最大丰度同位素精确原子量表 - 修正“质量数”原子量表为丰度最大同位素质量数 - 修正RTF历史窗口一处显示的问题 - 修正程序启动时不能装入原子量选项的bug * 改进了核心代码,提高效率 * 程序细节的改进 6.0.0: + 新增支持计算化学式中某些特定的基团的质量分数 + 自动保存用户设置在INI文件中 + 保存历史记录支持纯文本以及RTF两种格式 + 将元素统计结果复制到剪贴板时将有更多选择 + 简易模式窗口可以自动隐藏 - 彻底解决了当化学式中存在缩写基团时可能会发生的问题 * 程序启动时自动判断是否安装“Chemistry Numbers”字体以采取不同的显示策略,在没有字体的情

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值