一道字符串处理的题。
这题借助STL中的string处理起来要便利一些。
string有以下几点值得关注的地方:
- 获取字符串长度的size()/length()方法的时间复杂度为O(1)
- string::npos 是一个常数,本身的值为-1。由于是unsigned_int类型,因此实际上也可以认为是unsigned_int类型的最大值。它作为find()函数失配时的返回值。
题目链接在此。
字符串处理的题目在我看来都不简单,思考的容量比较大,对于规律的把握十分重要,边界以及特值的处理也都要考虑周全。
这个题目的意思比较简单:比较两个数的科学记数法是否相等,然后按要求输出信息即可。
以下是我们需要思考的内容:
- 对于科学记数法,主要的就是找出本体和指数。故下面讨论的目标都是围绕着找指数和本体进行的。(设精度为n)
- 我们可以将数据分成两种情况:
(1) 0.a1a2a3…
(2) b1b2…bm.a1a2a3… - 求指数(e):
对于第(1)种情况:e为小数点后第一位非零数位到小数点的之间的位数
对于第(2)种情况:若b1不为0,则e为小数点前的总位数m - 求本体:
对于第(1)种情况:其本体就是小数点后的第一位非0位往后的n位
对于第(2)种情况:其本体就是第一位非0位往后的n位(b1不为0)
本体位数不足n位时,用0补全。 - 如何判断一个数是属于以上哪种情况 以及 前导零 的问题
拿到一个数,首先要做的应该就是去除“前导零”。
在去除完前导零之后,通过判断第一位是否是小数点来判断是哪种情况。
在去除前导零过程中可以拿到本体(这里拿本体的思想采用:去除非本体的部分。本体部分的位置请看4,具体操作请看6)。 - 拿到本体
对于第(1)种情况:去除前导零、小数点、以及第一位非0位之前的所有数位之后的位即是本体
对于第(2)种情况:去除前导零、小数点,剩下数位即是题目所求本体
题目要求精度为n,只需要在上述的本体中截取前n位即可 - 特指0的处理(具体请看实现)
#include<stdio.h>
#include<string>
#include<iostream>
using namespace std;
int n;
string deal(string str, int &e){ //将字符串str的本体(n位)和指数解析出来
//去除前导零
while(str[0] == '0' && str.length() > 0){
str.erase(str.begin());
}
//分情况处理
if(str[0] == '.'){ //如果第一位是小数点,则如000.001234(去除前导零之后的数为.001234)
str.erase(str.begin()); //删除小数点
while(str[0] == '0' && str.length() > 0){ //找到小数点后第一个非零位,同时计算指数e,并删除与本体无关的位
e--; //指数减1
str.erase(str.begin()); //删除小数点后第一位非零位
}
} else{ //如果第一位不是小数点,则如0000123.4567(去除前导零后为123.4567)
int k = 0;
while(str[k] != '.' && k < str.length()){ //计算小数点前的有效位,同时计算指数e,并删除与本体无关的位
e++;
k++;
}
if(k < str.length()){ //while结束后,k < str.length(),说明遇到了小数点
str.erase(str.begin()+k); //删除小数点
}
}
//去除前导零和对特殊情况0进行处理
if(str.length() == 0){ //000.000或000或0的情况
e = 0;
}
//求本体n位
string res;
int num = 0;
int k = 0;
while(num < n){
if(k < str.length()){ //如果还有数字
res += str[k++]; //则将数字加到res的末尾
} else{ //如果不足n位
res += '0'; //则用0补齐
}
num++;
}
return res;
}
int main(){
string a, b;
cin >> n;
cin >> a >> b;
int ea = 0, eb = 0;
string resa = deal(a, ea);
string resb = deal(b, eb);
if(resa == resb && ea == eb){ //如果本体和指数都相等
cout << "YES " << "0." << resa << "*10^" << ea << endl;
} else{
cout << "NO " << "0." << resa << "*10^" << ea << " 0." << resb << "*10^" << eb << endl;
}
return 0;
}