分子量-记录状态的变量的精彩妙用

原题摘录-分子量(Molar Mass,ACM/ICPC seoul 2007,UVa1586)

给出一种物质的分子式(不带括号),求分子量.本题中的分子式只包括4种原子,分别为C,H,N,O,原子量为12.01,1.008,14.01,16.00.例如C6H5OH的分子量为6*12.01+5*1.008+1*16.00+1.008=94.108

详解

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <iostream>
#define maxn 256
using namespace std;
int main(int argc, char** argv)
{
    int sz;//字符数组中元素的个数 
    int cnt;//1,实时记录原子个数.2,在记录原子个数后,同时表征三个状态变量 0,1,-1 
    char buf[maxn];//输入由原子和数字组成的字符数组 
    char c;//记录数组中的每个元素,即每个原子和数字 ,均可以通过c转化 
        char s;//s=c,记录原子所对应的英文大写字母,为取W[]的内容(也即原子对应的质量)做准备 
        //int a; //a=c-'0,记录原子所对应的数字字符,为取原子对应的数量做准备


    double W[maxn];//记录每个原子所对应的质量  
    W['C']=12.01,W['H']=1.008,W['O']=16.0,W['N']=14.01;//初始化赋值 
    double ans=0;//记录实时的分子量 ,也即要求的答案
    cnt=-1;//初始化为-1,表示遇到了新原子 ,因为我们知道字符串第一个字符肯定是原子而不是数字
 
    scanf("%s",buf);//输入字符串  
    sz=strlen(buf);
    
    for(int i=0;i<sz;i++){
    char c=buf[i];
    if(isupper(c)){//原子大写字母处理 
        if(i) {
        if(cnt==-1) cnt=1;//标记一:原子后面不带数目,则原子个数化为1 
        ans+=W[s]*cnt;//计算的是上一次原子的质量 
        }
        s=c;//初始化本次原子 
        cnt=-1;//一分为二,下一个字符要么是大写原子字母,要么是数字.为原子处理标记一和原子个数数字处理标记二做准备 
    }
    else{ //原子个数数字处理 
        if(cnt==-1) cnt=0;//标记二:(cnt=-1,说明是新数,那么无旧数,则令旧数为0) 
        cnt=10*cnt+(c-'0');//旧数+新数 
        }    //一下新旧数的概念是针对多位数建立的;如12,那么对2来说,1就是旧数.
    }
    
    
    if(cnt==-1) cnt=1;//加上最后一个 
    ans+=W[s]*cnt;
    
    printf("%.3lf\n",ans);//按要求输出结果 
    return 0;
}

AC代码

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <iostream>
#define maxn 256
using namespace std;
int main(int argc, char** argv)
{
	int sz;
	int cnt;
    char buf[maxn];
	char c;
	    char s; 
	   
    double W[maxn];
    W['C']=12.01,W['H']=1.008,W['O']=16.0,W['N']=14.01;
    double ans=0;
    cnt=-1;
 
	scanf("%s",buf);
	sz=strlen(buf);
	
	for(int i=0;i<sz;i++){
	char c=buf[i];
	if(isupper(c)){
	    if(i) {
	    if(cnt==-1) cnt=1;
	    ans+=W[s]*cnt;
	    }
	    s=c;
	    cnt=-1;
	}
	else{ 
		if(cnt==-1) cnt=0;)
	    cnt=10*cnt+(c-'0');
	    }	
	}
	
	
	if(cnt==-1) cnt=1;
	ans+=W[s]*cnt;
	
	printf("%.3lf\n",ans);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值