目录
问题 A: 字符串处理
题目描述
读入两个字符串,字符串除了数字还可能包括 '—'、'E'、'e'、'.',相加之后输出结果,如果是浮点型,要求用科学计数法表示(最多包含10个有效数字)。
输入
输入包含多组测试数据。
每组输入占两行,每行一个字符串,测试数据保证字符串的构成严格按照题目中的描述。
输出
输出两个数字相加的结果,每组输出占一行。
样例输入
34.56
2.45e2
样例输出
2.7956e2
题解
以字符串形式存入,预处理两个字符串将e前后边的数值分离,并记录两数小数点后的位数和e后边相乘的位数相抵的结果,将两数化成原始形式扩大相同倍数使得去掉小数点并相加,如果是0或者整型直接输出,否则以科学计数法输出。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <string>
#include <algorithm>
using namespace std;
int flag, c;
long long solve(char *str, int *a){
flag = 0;//记录正负
c = 0, *a = 0;
long long s = 0;
int b;
int i;
for(i = 0; str[i]; i++){
if(str[i] == '-'){
flag = 1;
}
else if(str[i] == '.'){//存在小数点,c由0到1
c = 1;
}
else if(str[i] == 'e' || str[i] == 'E'){
sscanf(str + i + 1, "%d", &b);//b中存储e后边的数值
*a = *a + b;//小数点后的位数和e后边相乘的位数相抵
break;
}
else{
s = s * 10 + str[i] - '0';//e前边的字符转数值
*a = *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) != EOF){
s1 = solve(str1, &a1);
s2 = solve(str2, &a2);
//把e换算回来并同时扩大相同倍数
if(a1 < a2){
for(; a1 < a2; a2--){
s2 = s2 * 10;
}
}
else if(a1 > a2){
for(; a1 > a2; a1--){
s1 = s1 * 10;
}
}
a = a1;
s = s1 + s2;
if(s == 0){//和为0直接输出0并跳出循环
printf("0\n");
continue;
}
while(a < 0 && s % 10 == 0){
s = s / 10;
a++;
}
if(a >= 0){//非浮点型
printf("%lld", s);
int i;
for(i = 0; i < a; i++){
printf("0");
}
puts("");
continue;
}
flag = 0;//flag记录求和结果的正负
if(s < 0){
s = -s;
flag = 1;
}
ans = 1, w = 0;
while(ans <= s){
ans = ans * 10;
w++;
}
if(ans > 1){
ans = ans / 10;
w--;
}
if(flag){
printf("-");//负数输出'-'
}
printf("%lld", s / ans);//输出小数点前边的数值
if(ans > 1){
printf(".%lld", s % ans);//输出小数点后边的数值
}
printf("e%d\n", a + w);//输出e后边的数值
}
return 0;
}