原题:https://pintia.cn/problem-sets/994805342720868352/problems/994805413520719872
题目大意
给定计算机的有效数字N,和两个浮点数,将浮点数转成科学计数法表示,超出有效数字的部分直接截掉。
题目分析
用字符串或字符数组存储浮点数,先确定指数的大小:
- 搜索小数点的位置
dot
,如果不存在小数点,则dot = 字符串的长度
- 搜索从左到右第一个不为0,且不为小数点的数字
p
- 若
p
在dot
左边,则为整数部分,指数为dot - p
- 若
p
在dot
右边,则为小数部分,指数为dot - p + 1
- 若
p
超时字符串大小,则返回0
- 若
- 从左到右向浮点数的有效数字压入进另一个数组,注意不足N位,在后面补0
易错点
- 不足N位有效数字要补0
- 如果输入是0,不能只输出0,而且要在小数点后补有效数字位的0,和输出10^0
- 如果指数是0或者1也要输出
/* 1060 Are They Equal (25 分) */
#include<string>
#include<iostream>
using namespace std;
int find(string s, char c) { // 寻找c在字符串s中的位置,若不存在,返回字符串长度
int i;
for (i = 0; i < s.size() && s[i] != c; i++);
return i;
}
int signum(string& s) { // 返回数字s的第一个有效数字的位置
int indexdot = find(s, '.'); // 逗号所在分位
int i; // 第一个非0数字
for (i = 0; i < s.size() && (s[i] == '0' || s[i] == '.'); i++);
if (i <= indexdot) return indexdot - i; // 整数
else if (i == s.size()) return 0;
else return indexdot - i + 1; // 小数
}
string split(string& s, int n) {
// 取前面n位有效数字
string ans; ans.resize(n);
int index1 = 0, index2 = 0;
while (index1 < n && index2 < s.size()) {
if (index1 == 0 && s[index2] == '0') {
index2++;
}
else if (s[index2] == '.') {
index2++;
}
else ans[index1++] = s[index2++];
}
while (index1 < n) ans[index1++] = '0'; // 补0
return ans;
}
int main() {
int n;
string num1, num2;
cin >> n >> num1 >> num2;
int sig1 = signum(num1), sig2 = signum(num2);
string ans1 = split(num1, n), ans2 = split(num2, n);
if (sig1 == sig2 && ans1 == ans2)
printf("YES 0.%s*10^%d\n", ans1.c_str(), sig1);
else
printf("NO 0.%s*10^%d 0.%s*10^%d\n",ans1.c_str(),sig1,ans2.c_str(),sig2);
system("pause");
return 0;
}