目录
概述
这是一道算法题。
题目是:给一串分子式,求它的相对分子质量
只含C,H,O,N
C=12.01 g/mol
H=1.008 g/mol
O=16.00 g/mol
N=14.01 g/mol例如:
输入
C
C2
C2H2
c2h3o5n6
输出
12.01
24.02
26.036
191.104
分析
首先需要分析一下这个问题。
在计算摩尔质量的时候,主要是挨个扫描,找到对应的质量,累加,当遇到数字的时候,需要累乘。那么可以得到如下编码步骤:
- 定义一个输入数组,从开始到结尾扫描。
- 区分字符和数字。
- 将结果累加起来。
简单的实现方式
简单的实现方式,是指实现的思想简单,但是代码较多。
逻辑如下:
- 开始扫描输入的数组,并挨个判断是字符还是数字。
- 遇见不为指定字母的,即为数字(那么此刻就出现了一个问题,就是例如c2,先计算了c,遇见2之后又将c*2,然后会发现,多计算了一个c,所以每次遇见数字,需要减去上一个字符)。
- 数字-'0'(ASCII相减,就能得到数字的ASCII,但是并没有将字符型数字,转化为整型数字)。
- 设置两个中间变量来计算,总的值(一个用于保存当前扫描的到数字,一个用于保存之前的字符,而结果就是数字*字符,而且中间变量每次计算完当前的,字符数字组合之后,都要置为0,否则之后就会累加,计算错误)。
- 打印最后结果。
#include <stdio.h>
#include <string.h>
int main()
{
double c=12.01,h=1.008,o=16.00,n=14.01,sum,temp1,temp2;//temp1存储数字,temp2存储数字前的字符 ;
int i;
char chem[100];
double ipt[100];//输入字符
sum=0;
scanf("%s",chem);
for(i=0;i<strlen(chem);i++)
{
if(chem[i]=='c')
{
sum=sum+c;
}
if(chem[i]=='h')
{
sum=sum+h;
}
if(chem[i]=='o')
{
sum=sum+o;
}
if(chem[i]=='n')
{
sum=sum+n;
}
else{
temp1=chem[i]-'0'; //存储数字
//(此时为什么要-0呢?因为0的ASCII为48,而字符类型的数字,与数字类型的数字刚好差48,当前此时也能自己写一个,字符型转数字型的方法来实现)
if(chem[i-1]=='c')
{
temp2 = c;
}
if(chem[i-1]=='h')
{
temp2 = h;
}
if(chem[i-1]=='o')
{
temp2 = o;
}
if(chem[i-1]=='n')
{
temp2 = n;
}
sum = temp1*temp2+sum-temp2;
temp1=0;
temp2=0;//每次结束之后将temp1和temp2的值置为0,以免后续累加
}
printf("第%d次sum值为%.3f\n",i,sum);
}
printf("%.3f\n",sum);
return 1;
}
那么这种方法的最大问题是什么呢?
例如c2hc等后面跟的只是个位数的元素角标,这个方法当然没有问题,有没有发现,当c22这样的数字出现的时候,这个方法计算出来的是错误的数字。
有没有改进的办法呢?有,但是会越写越复杂,越写越多,这种方法,就是类似于面向问题编程,出现一个解决一个,这种思想,用于JAVA编程当然可以,但是用于算法,就没那么用了。
复杂一点的办法
这种办法相对代码量没有那么多,但是存在一些地方还是需要细细理解的。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
int i=0,j=0,k=0;
float sum=0;
int count=0;
char element[5], substance[50];
char elements[100][5]={"C","H","O","N"};
float index[100]={12.01, 1.008, 16.00, 14.01};
int num_ele=0;
while(scanf("%s",substance)){
sum=0;
for(i=0;i<strlen(substance);i++){
if(isupper(substance[i])){ //isupper()用于检测,一个字符是否是大写字母。
if(islower(substance[i+1])){ // islower()用于检测,一个字符是否是小写字母
num_ele = 2;
}
else {
num_ele = 1;
}
if(num_ele){
k=i;
for(j=0;j<num_ele;j++,k++){
element[j] = substance[k];
}
element[j] = 0;
num_ele=0;
j=0;
while(1){
if(!strcmp(element,elements[j])){ //int strcmp(const char *str1, const char *str2) 把 str1 所指向的字符串和 str2 所指向的字符串进行比较。
break;
}
j++;
}
sum+=index[j];
}
}
else if(isdigit(substance[i])){
count = 0;
while(isdigit(substance[i])){
count = count * 10 + (substance[i] - '0');
i++;
}
i--;
count--;
sum+=(index[j]*count);
}
}
printf("The molar mass of the %s is: %.3f g/mol\n",substance,sum);
}
return 0;
}
最后才算是能够完整的解决。