下午打了一场ICPC的区域赛,感觉字符串的练习还是不够,晚上找了到细节字符串题目来练练手,特此记录
题目
4944: 字符串处理
Time Limit: 1 Sec Memory Limit: 32 MB
Submit: 153 Solved: 65
[Submit][Status][Web Board]
Description
读入两个字符串,字符串除了数字还可能包括 ‘—’、‘E’、‘e’、’.’,相加之后输出结果,如果是浮点型,要求用科学计数法表示(最多包含10个有效数字)。
Input
输入包含多组测试数据。
每组输入占两行,每行一个字符串,测试数据保证字符串的构成严格按照题目中的描述。
Output
输出两个数字相加的结果,每组输出占一行。
Sample Input
34.56
2.45e2
Sample Output
2.7956e2
思路解释
这道题目涉及到一些字符串的细微操作,首先我们先把读入的字符串进行初始化,把字符串拆解成以下几个部分:小数点前,小数点后,e以及e之后这四个部分,然后分别进行累加计算
这里由于涉及到e后数字和小数点后的抵消关系,我们引入a,来保存预处理过程中能够抵消之后留下的10的幂次
预处理的代码如下:
int flag,c;
long long solve(char *str,int *a)
{
flag=0; //记录正负
c=0; *a=0;
long long s=0; int b;
for(int i=0;str[i];i++)
{
if(str[i]=='-') flag=1;
else if(str[i]=='.') c=1; //存在小数点,c由0->1
else if(str[i]=='e'||str[i]=='E')
{
sscanf(str+i+1,"%d",&b); //b中存储e后边的数值
*a+=b; //小数点后的位数和e后边相乘的位数相抵
break;
}
else
{
s=s*10+str[i]-'0'; //e前边的字符一步步转数值
*a-=c; //记录小数点后的位数
}
}
if(flag) s=-s;
return s; //返回e前边的数值
}
AC代码
#include<bits/stdc++.h>
using namespace std;
int flag,c;
long long solve(char str[],int *a)
{
long long s = 0;
int b;
flag = *a = c = 0;
for(int i=0;str[i];++i){
if(str[i]=='.')c = 1;
else if(str[i]=='e'||str[i]=='E'){
sscanf(str+i+1,"%d",&b);
*a += b;
break;
}else if(str[i]=='-')flag = 1;
else{
s = s*10 + str[i]-'0';
*a -= c;
}
}
if(flag)s = -s;
return s; //返回e前边的数值
}
int main(){
char str1[50],str2[50];
long long s,s1,s2,ans;
int a1,a2,a,w,flag;
while(~scanf("%s%s",str1,str2))
{
//预处理两个字符串并得到相应的a
s1=solve(str1,&a1);
s2=solve(str2,&a2);
//把e换算回来并同时扩大相同倍数
//直到两个相加数的进制位相同
if(a1<a2)
{
for(;a1<a2;a2--) s2*=10;
}
else if(a1>a2)
{
for(;a1>a2;a1--) s1*=10;
}
a=a1; s=s1+s2;
if(!s) //特殊判断和为0直接输出0并跳出循环
{
printf("0\n");
continue;
}
while(a<0&&s%10==0)
{
s/=10; a++;
}
if(a>=0) //非浮点型
{
printf("%lld",s);
for(int i=0;i<a;i++) printf("0");
puts(""); continue;
}
flag=0; //flag记录求和结果的正负
if(s<0)
{
s=-s; flag=1;
}
ans=1;w=0;
//ans就是浮点数整数部分,w表示小数点移动的位数
while(ans<=s)
{
ans*=10; w++;
}
if(ans>1)
{
ans/=10; w--;
}
//负数输出'-'
if(flag) printf("-");
//输出小数点前边的数值
printf("%lld",s/ans);
//输出小数点后边的数值
if(ans>1) printf(".%lld",s%ans);
//输出e后边的数值
printf("e%d\n",a+w);
}
return 0;
}
总结
这道题有些点挺细的,然后有些地方处理的不好就很麻烦,总之,可以作为一个处理字符串的方法吧,学习一下