分子量 (Molar Mass,ACM/ICPC Seoul 2005,UVa1586)
习题 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)的更多相关文章
- 习题3-2 分子量(Molar Mass, ACM/ICPC Seoul 2007, UVa1586)
#include<stdio.h> #include<string.h> #include<ctype.h> double getweight(char x) { ...
- 分子量(Molar Mass,ACM/ICPC Seoul 2007,UVa 1586)
#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){ char s[20]; scanf ...
- 分子量 (Molar Mass,ACM/ICPC Seoul 2007,UVa 1586)
解题思路: 1.将分子量用double 数组记录下来 2.将字符串存储在字符数组中,从头向后扫描,一直记住“字母”,对下一个字符进行判断,是否是数字,如果是数字:用一个整数记录,本代码中用的sum,同 ...
- UVa 1586 - Molar Mass - ACM/ICPC Seoul 2007 - C语言
关键在于判断数字是两位数还是单位数,其他部分没有难度. #include"stdio.h" #include"string.h" #include"c ...
- [C++]最小生成元 (Digit Generator, ACM/ICPC Seoul 2005, UVa1583)
Question 例题3-5 最小生成元 (Digit Generator, ACM/ICPC Seoul 2005, UVa1583) 如果x+x的各个数字之和得到y,就是说x是y的生成元.给出n( ...
- 生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)
如果x加上x的各个数字之和得到y,就说x是y的生成元.给出n(1≤n≤100000),求最小 生成元.无解输出0.例如,n=216,121,2005时的解分别为198,0,1979. [分析] 本题看 ...
- 得分(Score,ACM/ICPC Seoul 2005,UVa 1585)
#include<stdio.h> int main(void) { char b; int t,cou,sum; scanf("%d",&t); getcha ...
- 生成元(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 ...
- 得分(Score, ACM/ICPC Seoul 2005,UVa 1585)
#include<cstdio>#include<cstdlib>#include<cstring>int main(){ char s[80];//输入OOXXO ...
随机推荐
- JS获取对象“属性和方法”的方法
平时在写的代码过程中,经常会遇到对对象Object的数据处理.而在对对象的数据处理中,操作最频繁的是“数据引用”.“值的修改”.“获取关键字(属性)”.平时最烦的也是“获取关键字”,经常忘记怎么去获取 ...
- Pig order by用法举例
sorted = order data by $0; 数值类型按照数值大小比较 chararray类型按照字符的字典顺序比较 bytearray按照字节的字典顺序比较 复杂类型(map.tuple ...
- idea 版本控制忽略文件、文件夹设置
setting 或者底部的 设置 忽略某个文件 后面选择框可以去选择 忽略某个文件夹 后面选择框可以去选择 忽略某种文件 后面输入填写如: *.txt
- [域|Domain] The trust relationship between this workstation and the primary domain failed 此工作站和主域间的信任关系失败
PS> $cred = Get-Credential domain.sample.com;Reset-ComputerMachinePassword -Credential $cred -Ser ...
- Entity Framework对同一张表配置一对多关系
在实际的项目开发中,可能会遇到同一张表同时保存自身和上级(或下级)的信息(一般是通过设置一个上级主键[ParentId]的列与主键[Id]关系) 例如:城市库,有国家.省.市...,省的ParentI ...
- Mybatis工作原理(含部分源码)
MyBatis的初始化 1.读取配置文件,形成InputStream String resource = "mybatis.xml"; // 加载mybatis的配置文件(它也加载 ...
- KHFlatButton
KHFlatButton https://github.com/kylehorn/KHFlatButton 效果: 对于自己做demo来说,每次设置button就不用这么折腾了,几句话就行了,非常爽: ...
- 铁乐学python_day24_面向对象进阶1_内置方法
铁乐学python_day24_面向对象进阶1_内置方法 题外话1: 学习方法[wwwh] what where why how 是什么,用在哪里,为什么,怎么用 学习到一个新知识点的时候,多问问上面 ...
- 铁乐学python_day10_作业
1.继续整理函数相关知识点,写博客. 2.写函数,接收n个数字,求这些参数数字的和.(动态传参) def sum_n(*args): sum = 0 for i in args: sum += i r ...
- 【教程】【FLEX】#006 控件位置的拖动
上一篇笔记学习了怎么从 把一个控件拖放到另外一个控件里面(即 A --> B里面). 而现在呢,则是学习 怎么把 A 拖到另外一个位置. (A -->A位置改变): 先说一下实现的思路( ...