任给一个十进制正数 M>0 (M 可能为整数或小数,且最多包含 200 位数字)。写一个程序将其转换成科学计数法表示,形式为 aFb。其中 1≤a<10 且不含前置 0,a 的长度为给定精度 p (p 包括 a 中整数及小数部分但不包含小数点)。a 的值由四舍五入方法确定,M 中有效数字长度小于 p 时,后面填充 0 补足。b 为指数,b=0 时,省略指数部分。
输入格式
第 1 行:一个整数 T(1≤T≤10)为问题数。
每组测试数据为一行,包含两个数字,之间由一个空格分开。第一个数字是待转换数字 M,第二个数字是要求的输出精度 p (1<p≤30)。
输出格式
对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0: 等)。
然后接下来一行中输出给定数字的科学计数法表示。
样例
input
3
123456789 8
0.0045678 3
1.8 4
output
case #0:
1.2345679F8
case #1:
4.57F-3
case #2:
1.800
思路:
这是一道踩了坑的题。首先就是进位问题。我的思路是先算出aFb中的b部分,再提取数字出来处理进位。
但忘记了如果是99999999的情况,进位会导致溢出,以及串长度小于p的情况。
所以码完题之后又借鉴了一下dalao们的做法。
代码
相当粗鄙的解法。
#include <cctype>
#include <iostream>
#include <string>
using namespace std;
int p, t, b;
string m;
int main() {
cin >> t;
for (int k = 0; k < t; k++) {
cin >> m >> p;
while (m.front() == '0')
m.erase(m.begin());
if (m.front() == '.') {
for (int i = 1; i < m.length(); i++) {
if (m[i] > '0') {
b = -i;
break;
}
}
} else
b = (m.find('.') == m.npos ? m.length() : m.find('.')) - 1;
string copy{};
for (auto i : m) {
if (isdigit(i))
copy += i;
}
while (copy.front() == '0')
copy.erase(copy.begin());
if (copy.length() > p) {
if (copy[p] >= '5')
copy[p - 1]++;
for (int i = p - 1; i >= 1; i--) {
copy[i - 1] += copy[i] / ('9' + 1);
copy[i] %= '9' + 1;
if (copy[i] < '0')
copy[i] += '0';
}
if (copy[0] == '9' + 1) {
copy[0] %= ('9' + 1);
if (copy[0] < '0')
copy[0] += '0';
copy.insert(copy.begin(), '1');
b++;
}
} else {
for (int i = copy.length() - 1; i < p; i++)
copy += '0';
}
cout << "case #" << k << ":\n" << copy[0] << ".";
for (int i = 1; i < p; i++)
cout << copy[i];
if (b)
cout << "F" << b;
cout << endl;
}
return 0;
}
2
dalao的优美代码。
#include<bits/stdc++.h>
using namespace std;
auto const P(30);
int main()
{
int T; cin >> T;
for(int cs = 0; cs < T; cs++)
{
cout << "case #" << cs << ":\n";
string m; int p; cin >> m >> p; m +='0'; // 开头补个0防溢出
int b = 0;
if(auto dot = m.find('.'); dot != m.npos)
{
b = dot - m.length() + 1;
m.erase(dot, 1);
}
auto nz = m.find_first_not_of('0'); // nz: not_zero
b += m.length() - nz - 1;
m += string(P, '0'); // 不管精度够不够,末尾先补它30个0
m[nz + p - 1] += m[nz + p] >= '5';
for(int i = nz + p - 1; m[i] > '9'; i--)
{
m[i] -= 10; m[i - 1] += 1;
}
if(m[nz - 1] - '0') // 把类似10.0F1的情况改成1.0F2
{
nz -= 1; b += 1;
}
cout << m[nz] << ".";
for(size_t i = nz + 1; i < nz + p; i++)cout << m[i];
if(b)cout << "F" << b;
cout << "\n";
}
}