摩尔质量的计算

目录

概述

分析 

简单的实现方式


概述

这是一道算法题。

题目是:给一串分子式,求它的相对分子质量
只含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

分析 

首先需要分析一下这个问题。

在计算摩尔质量的时候,主要是挨个扫描,找到对应的质量,累加,当遇到数字的时候,需要累乘。那么可以得到如下编码步骤:

  1. 定义一个输入数组,从开始到结尾扫描。
  2. 区分字符和数字。
  3. 将结果累加起来。 

简单的实现方式

简单的实现方式,是指实现的思想简单,但是代码较多。

逻辑如下:

  1. 开始扫描输入的数组,并挨个判断是字符还是数字。 
  2. 遇见不为指定字母的,即为数字(那么此刻就出现了一个问题,就是例如c2,先计算了c,遇见2之后又将c*2,然后会发现,多计算了一个c,所以每次遇见数字,需要减去上一个字符)。
  3. 数字-'0'(ASCII相减,就能得到数字的ASCII,但是并没有将字符型数字,转化为整型数字)。
  4. 设置两个中间变量来计算,总的值(一个用于保存当前扫描的到数字,一个用于保存之前的字符,而结果就是数字*字符,而且中间变量每次计算完当前的,字符数字组合之后,都要置为0,否则之后就会累加,计算错误)。
  5. 打印最后结果。
#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;
}

最后才算是能够完整的解决。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ybbgrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值