习题3-2 Molar Mass Uva1586

两种思路:

  • 一个是循环,当前数组元素如果为字母,判断之后有多少数字,一次性计算,如果循环再碰到数字就跳过。
  • 另一个是循环过程中,判断当前取到的是数字还是字母,如果是字母,则记下它的原子质量,继续取下一个。如果是数字,就把记录的上个原子质量*当前的数字。

▲.捣鼓了很久才注意到的是分离数组中数字时,不是用int(s[i])而是s[i]-'0'

    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdlib.h>
    
    #define maxn 105
    char s[maxn];
    int main()
    {
        int T;
        scanf("%d",&T); //T个输入数据
        while(T--)
        {
            int i;
            double single=1.0,sum=0.0;
            scanf("%s",s);
            int len = strlen(s);
            for(i=0;i<len;i++)
            {
                if (isalpha(s[i]))      
                {
                    if(s[i]=='C') single=12.01f;
                    else if(s[i]=='H') single=1.008f;
                    else if(s[i]=='O') single=16.00f; 
                    else if(s[i]=='N') single=14.01f;
                     //记录当前元素的原子质量
                    if(s[i+1] != '\0'){
                        if( isalpha( s[i+1]) ) sum += single*1.0;
                        //如果下一个是字母如OH,就直接加上上个原子的原子质量
                        else if (isdigit(s[i+1])){ //如果是数字
                            int j=i+1;
                            int total=0;
                            do{
                                total = 10*total + (s[j]-'0');
                                j++;
                            }while(s[j] != '\0' && isdigit(s[j]) );
                            //把数组内的数字组合成合理的整数。将1、2==>12
                            sum += single*total;
                            }
                        //else sum += single*1.0;    
                        }
                    else sum += single*1.0; //处理是'\0'情况,C6H5OH的H
                }
                else continue;  //如果是数字就继续循环
            }
            printf("%.3f\n",sum);
        }
        return 0;
    }
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdlib.h>//system("Pause");调试的时候用的
    
    #define maxn 105
    char s[maxn];
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int i;
            double single=1.0,sum=0.0;
            scanf("%s",s);
            int len = strlen(s);
            int flag = 0;   //通过该标志判断上一个元素是否是字母
            for(i=0;i<len;i++)
            {
                if (isalpha(s[i]))
                {
        if(s[i]=='C')      {if(flag==1) sum +=single;single=12.01f;flag=1;}
        else if(s[i]=='H') {if(flag==1) sum +=single;single=1.008f;flag=1;}
        else if(s[i]=='O') {if(flag==1) sum +=single;single=16.00f;flag=1;}
        else if(s[i]=='N') {if(flag==1) sum +=single;single=14.01f;flag=1;}
        //如果上一个数组元素为字母(flag==1),就直接加上上一个原子质量。
        //同时要设置当前数组元素为字母(flag=1)
                }
                else if (isdigit(s[i]))
                {
                    flag = 0;   //设置当前元素为数字
                    int j=i;
                    int total=0;
                    do{total = 10*total + (s[j]-'0');
                        j++;
                    }while(s[j] != '\0' && isdigit(s[j]) );
                    //处理C6H12O6中12这种情况,数字后面没有内容或是字母都结束
                    sum += single*total;
                }
            }
            if(flag == 1)printf("%.3f\n",sum+single);
            //C6H5OH处理最后正好是两个字母的情况,因为判断到最后一个H的时候,sum直接+=了single(0),同时记录了H但没有加上
            else printf("%.3f\n", sum);
        }
        return 0;
    }

再奉上mrcrack的做法:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

char s[1000+10];
float value(char c){//根据不同的原子,获取相应的原子量 
    float v;
    switch(c){
        case 'C':
            v=12.01;
            break;
        case 'H':
            v=1.008;
            break;
        case 'O':
            v=16.00;
            break;
        case 'N':
            v=14.01;
            break;
    }
    return v;
} 

int main(){
    int T;
    int len;
    int i;
    float sum;
    int m;  //原子的数目
    int k;
    scanf("%d",&T);
    while(T--){
        sum=0;
        scanf("%s",s);
        len=strlen(s);
        for(i=0;i<len;i++){
            if(isalpha(s[i])){
                if(i+1<len){        //元素没越界
                    if(isdigit(s[i+1])){//下一个元素是数字 
                        k=1;
                        m=0;
                        while(i+k<len && isdigit(s[i+k])){
                            //单个数字连接成一个多位数的数字 
                            m*=10;
                            m+=s[i+k]-'0';
                            k++;
                        }
                        sum+=value(s[i])*m;
                        i=i+k-1;//重新开始,i要自加1,故先将i减1 
                    }
                    else{//下一个元素是字母 
                        m=1;
                        sum+=value(s[i])*m;
                    } 
                }
                else{//下一个元素已越界 
                    m=1;
                    sum+=value(s[i])*m;
                }
            }
        }
        printf("%.3f\n",sum);
    }
    return 0;
}

他的做法跟我的二类似,他在判断是否越界上跟我有略微不同i+k<lens[j+1] != '\0'.

猜你喜欢

转载自www.cnblogs.com/nymrli/p/9548418.html