根据题目思路很明确,就是要分辨出分子式的字母和数字。
当判断为字母时,将字母缓存,计算现在的分子式,将数字缓存清空。
当判断为数字时,将数字缓存*10再加上新获取的数字。
当分子式结束时,判断最后一个字符进行上述的步骤。
下面是代码:
#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
const char rev[]= "CHON0123456789";
const double num[] = { 12.01, 1.008, 16.00, 14.01 };
int a,b;
cin >> a;
while ((b = getchar()) != EOF && b != '\n');//清空缓存区
while (a--)
{
double tempc = 0; //缓存当前字母的分子量
int tempi=0;//缓存数字
int c=0;
double res=0.0;
while ((c = getchar()) != EOF && c != '\n')
{
int i;
for ( i = 0; c != rev[i]; i++);//获取字符在数组的位置
//cout << i << endl;
if (i < 4)//遇到字母时,就要统计一下分子量,并缓存当前字母的分子量并清零数字缓存
{
if (tempi) res += tempi*tempc;
else res += tempc;
tempc = num[i];
tempi = 0;
//cout << res << endl;
}
else//遇到数字时,要将数字存入tempi中,再读取字符
{
tempi = tempi * 10 + (c - '0');
continue;
}
}
if (tempi) res += tempi*tempc;//如果是以数字结尾,就要补上对分子量的计算
else res += tempc;
printf("%.3f\n", res);
}
}
最后很无奈,估计是在线评测系统的缓存区和本地有所不同,只好采用另一种方法了,把getchar 用scanf来代替掉,下面是代码
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define maxn 100
int main()
{
const char rev[] = "CHON0123456789";
const double num[] = { 12.01, 1.008, 16.00, 14.01 };
int a, b;
cin >> a;
while (a--)
{
double tempc = 0;
int tempi = 0;
char c[maxn];
double res = 0.0;
scanf("%s", c,80);//原来代码是scanf_s("%s", c,80);在线测评识别不了只得替换
for (int j = 0; j < strlen(c);j++)
{
int i;
for (i = 0; c[j] != rev[i]; i++);
if (i < 4)
{
if (tempi) res += tempi*tempc;
else res += tempc;
tempc = num[i];
tempi = 0;
}
else
{
tempi = tempi * 10 + (c[j] - '0');
continue;
}
}
if (tempi) res += tempi*tempc;
else res += tempc;
printf("%.3f\n", res);
}
}
换成scanf之后,就不用考虑缓存区的问题了,鲁棒性更强了。