习题 3-3 分子量 (Molar Mass,ACM/ICPC Seoul 2005,UVa1586)

    给出一种物质的分子式(不带括号),求分子量。本题中的分子式只包含4种原子,分别为C,H,O,N,原子量分别为12.01,1.008,16.00,14.01(单位:g/mol)。例如,C6H5OH的分子量为94.108g/mol。

【我的思路:】
首先设想会有哪些情况,然后去分析每种情况怎么解决,比如:
问题一:字母+字母
    CHO怎么判断,怎么计算?
问题二:字母+数字
    C,C1,C2这三个会不会都不一样,怎么判断?
问题三:字母+多位数字
    C6,C66,C666怎么判断?
问题四:数字+字母
    C6H,O2O怎么判断?

根据上面这四种情况来整理思路,一个一个解决,然后将相似的归类,最后整合,编程到一个程序中去。

【代码详解:】【源代码在文章最后】

最最开头,我们是需要头文件的。

#include "stdio.h"//不能少的
#include "string.h"//主要有一个求字符串长度的函数
#include "ctype.h"//这里需要用到几个函数,一个用来判断是否为大写字母,还有一个用来判断是否为数字

接下来首先,我们要来定义数组,需要哪些数组,我们需要记录C,H,O,N中的单分子的摩尔质量分别是多少,要用到“实型数组” double w[] 来存放。

然后,我们需要输入字符串啊,当然要一个“字符型数组” char s[] 。

这里在定义数组的时候要注意,为了有足够的空间放字符串,用2^8个空间,也就是256,别问为什么,因为我喜欢。其实也就是为了稍微大点的空间来存放。当然,还要考虑到那四个元素的ASCII码最高是多少,为了减少思考,就不用2^7=128了,因为房间刚刚好显得憋屈,所以用大一号的空间。还有,我的习惯是超过100的数组我就会放在主函数外面定义,防止空间过大导致运行的时候异常退出。

char s[];//记录分子串
double w[];//存放单个分子量

接下来进入主函数

int main()
{

这里要将C,H,O,N的摩尔质量存放到w[256]的数组中去。

w['C']=12.01,w['H']=1.008,w['O']=16.00,w['N']=14.01;//大写的分子的物质的量

接下来就要开始循环了,有些临时用的数据可以在循环体中定义,不用在外面定义占空间。

while(scanf("%s",s)==)
{//需要判断单个字母和多个数字的情况

这时候要想到,上面的这种写法是只要有输入就不会停止的,也就是说可以不断判断字符串的,那么每次开始的时候,需要将分子量的和sum清零。还要有暂时存放分子量的变量t,其次就是要有记录连续数字的一个整型变量cnt。对了,还有字符串的长度n,可以通过strlen()函数来取得。

double sum=;//每组分子串的开始时候分子量清零
double t=;//用来暂存单个分子量的和
int cnt=;//用来记录连续数字字符的值 ——即分子个数
int n=strlen(s);//记录分子串长度

接下来就要从字符串头开始循环到结尾来查找对应的是字母还是数字。

for(int i=;i<n;i++)
{

然后为了方便简写代码,就把s[i]存放到字符型变量cun中,放入单个字符。

char cun=s[i];//单个字符暂时存放在c中

既然刚刚已经记录了单个字符,那么这个字符是什么呢?接下来我们就要来判断什么字符,首先从简单地来判断,如果是字母怎么办?那么就把对应的分子量加上,并且放到sum中去。

if(isupper(cun))//是单个大写字母
{
  t=w[cun];//把字母的数值代入临时分子量的和
  sum+=t; //累加字母字符对应的分子量
}

好了,这样一来“问题一”就解决了,遇到字母就加上。

接下来就开始复杂的数字情况,为什么复杂,因为有单个数字的情况,有多个数字的情况,而且这个“多个”还不一定是两个。那么就开始分析数字的情况。

如果遇到数字了,那么说明前一个字母后面是有数字的,不管他是多少,都要把刚刚加上的单个分子量减掉,防止后面赋值多余,这个时候就体现了临时分子量t的作用了。
减掉之后,看看当前这个数字是多少,用上cnt存放cun-'0',当读取到这是数字之后,那就一鼓作气看看后面到底还有多少数字。
开始一个while小循环,如果后一个s[i+1]也是数字,那么就把当前的数字乘十加上后面那个数字,这里的后一个数字没有记录过,也没有变量储存,只有直接引用 s[i+]-'' ,然后i++继续往后找,直到后一个不是数字为止。
这里的i的作用除了小循环,还有让for循环中不在重蹈覆辙,判断过得就不要管了。
然后得到了最后的数字,存放在cnt中,这时候就要把临时分子量t中的数值乘上分子个数cnt,得到这个多分子的分子量sum,并且累加上去,这就是前面减去单个分子量的作用,防止这里的赋值多余。

if(isdigit(cun))//这个是数字的情况
{//需要进一步判断是否为多位数字
  sum-=t;//先减去前一个所加的单个分子量,方便后面整体加上
  cnt=cun-'';//读取数字字符的值
  while(isdigit(s[i+]))//判断后一个字符是否为数字字符
  {
    cnt*=;//当前读取的数字乘十
    cnt+=s[i+]-'';//在加上后一个数字当作个位
    i++;//小循环中判断连续的数字字符 ,让下一个for循环不在重复循环已经判断过的连续数字
  }
  sum+=t*(cnt);//单个分子量t乘上分子个数cnt
}

好了,到这里判断比较复杂的数字情况也结束了,这就解决了字母+数字的“问题二”和“问题三”。
这个时候for循环也可以结束了。

 }

for循环结束之后要输出最后结果,格式要固定好,摩尔质量中小数位数最多的是3位,那么结果也设置成3位实型 "%.3lf" 。

printf("%.3lf\n",sum);

这时候while循环整体也可以结束了,最后还要 return ; 然后程序结束。

  }
  return ;
}

源代码://应该是AC码,各位大神可以亲测一下,如果是的话希望支持一下。

#include "stdio.h"
#include "string.h"
#include "ctype.h"
char s[];//记录分子串
double w[];//存放单个分子量 int main()
{
w['C']=12.01,w['H']=1.008,w['O']=16.00,w['N']=14.01;//大写的分子的物质的量
while(scanf("%s",s)==)
{//需要判断单个字母和多个数字的情况
double sum=;//每组分子串的开始时候分子量清零
double t=;//用来暂存单个分子量的和
int cnt=;//用来记录连续数字字符的值 ——即分子个数
int n=strlen(s);//记录分子串长度
for(int i=;i<n;i++)
{
char cun=s[i];//单个字符暂时存放在c中
if(isupper(cun))//是单个大写字母
{
t=w[cun];//把字母的数值代入临时分子量的和
sum+=t; //累加字母字符对应的分子量
}
if(isdigit(cun))//这个是数字的情况
{//需要进一步判断是否为多位数字
sum-=t;//先减去前一个所加的单个分子量,方便后面整体加上
cnt=cun-'';//读取数字字符的值
while(isdigit(s[i+]))//判断后一个字符是否为数字字符
{
cnt*=;//当前读取的数字乘十
cnt+=s[i+]-'';//在加上后一个数字当作个位
i++;//小循环中判断连续的数字字符 ,让下一个for循环不在重复循环已经判断过的连续数字
}
sum+=t*(cnt);//单个分子量t乘上分子个数cnt
}
}
printf("%.3lf\n",sum);
}
return ;
}

作为初学者的我在经过两天的头疼之后写出来的,第一天用的方法比较繁琐,放弃了。第二天一天时间,最后在浴室想出了解决方法的,才得到了这40行算是简短的代码,不知道程序鲁棒性怎么样,欢迎大神指点一二。

分子量 (Molar Mass,ACM/ICPC Seoul 2005,UVa1586)的更多相关文章

  1. 习题3-2 分子量(Molar Mass, ACM/ICPC Seoul 2007, UVa1586)

    #include<stdio.h> #include<string.h> #include<ctype.h> double getweight(char x) { ...

  2. 分子量(Molar Mass,ACM/ICPC Seoul 2007,UVa 1586)

    #include<stdio.h>#include<stdlib.h>#include<string.h>int main(){ char s[20]; scanf ...

  3. 分子量 (Molar Mass,ACM/ICPC Seoul 2007,UVa 1586)

    解题思路: 1.将分子量用double 数组记录下来 2.将字符串存储在字符数组中,从头向后扫描,一直记住“字母”,对下一个字符进行判断,是否是数字,如果是数字:用一个整数记录,本代码中用的sum,同 ...

  4. UVa 1586 - Molar Mass - ACM/ICPC Seoul 2007 - C语言

    关键在于判断数字是两位数还是单位数,其他部分没有难度. #include"stdio.h" #include"string.h" #include"c ...

  5. [C++]最小生成元 (Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

    Question 例题3-5 最小生成元 (Digit Generator, ACM/ICPC Seoul 2005, UVa1583) 如果x+x的各个数字之和得到y,就是说x是y的生成元.给出n( ...

  6. 生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

    如果x加上x的各个数字之和得到y,就说x是y的生成元.给出n(1≤n≤100000),求最小 生成元.无解输出0.例如,n=216,121,2005时的解分别为198,0,1979. [分析] 本题看 ...

  7. 得分(Score,ACM/ICPC Seoul 2005,UVa 1585)

    #include<stdio.h> int main(void) { char b; int t,cou,sum; scanf("%d",&t); getcha ...

  8. 生成元(Digit Generator ,ACM/ICPC Seoul 2005 ,UVa 1583)

    生成元:如果 x 加上 x 各个数字之和得到y,则说x是y的生成元. n(1<=n<=100000),求最小生成元,无解输出0. 例如:n=216 , 解是:198 198+1+9+8=2 ...

  9. 得分(Score, ACM/ICPC Seoul 2005,UVa 1585)

    #include<cstdio>#include<cstdlib>#include<cstring>int main(){ char s[80];//输入OOXXO ...

随机推荐

  1. Android自定义View探索—生命周期

    Activity代码: public class FiveActivity extends AppCompatActivity { private MyView myView; @Override p ...

  2. mysql 免安装版

    通过MySQL安装程序(.msi文件)来安装虽然简洁高效,但不够灵活,所以我们这里介绍免安装版. 1.  下载: 进入官网-->Downloads-->Community(社区版)--&g ...

  3. springboot学习入门之一---基本了解

    1springboot基本了解 1.1概述 Spring Boot不是一门新技术,本质上就是spring. 特性: 1) 零配置(或很少配置) 2) 四个核心:(ASCA) 3.1)自动配置:spri ...

  4. 转: Dubbo远程调用服务框架原理与示例

    Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和  Spring 框架无缝集成. 主要核心部件: Remoting:  网络通 ...

  5. Python DDT(data driven tests)模块心得

    关于ddt模块的一些心得,主要是看官网的例子,加上一点自己的理解,官网地址:http://ddt.readthedocs.io/en/latest/example.html ddt(data driv ...

  6. SQLServer 查询使用键查找时锁申请及释放顺序

    最近看了高兄的一篇文章,Sql Server 高频,高并发访问中的键查找死锁解析,很有收获,里面讲到了键查找引起的死锁问题. 当然看的过程中,其实自己有个疑问: 对于键查找这类查询,会申请哪些锁,锁申 ...

  7. 在 Azure VM 上安装 LAMP Web 服务器

    本文逐步讲解如何在 Azure 中的 Ubuntu VM 上部署 Apache Web 服务器.MySQL 和 PHP(LAMP 堆栈). 如果想要部署 NGINX Web 服务器,请参阅 LEMP ...

  8. Ogre学习教程:Ogre1.8.1+VS2010环境配置2(转)

    之前按照前面一篇文章提到的部署了ogre1.9,后来查询资料,有的提到关于vs2010还是安装ogre1.8比较稳定,由于是小白,又比对着几篇文章重新配置了一遍. 从一开始的什么都不会,到现在能知道每 ...

  9. 第八章 计时器(DIGCLOCK)

    /*-------------------------------------- DIGCLOCK.C -- Digital Clock (c) Charles Petzold, 1998 ----- ...

  10. codeforces 424D Biathlon Track

    codeforces 424D Biathlon Track 题意 题解 代码 #include<bits/stdc++.h> using namespace std; #define f ...