题目描述
知识点
STL string的用法
实现
码前思考
- 对于这种格式转换的题目,最常用的方法就是写很多个
if-else
语句,也就是 分情况,将问题模块化,从宏观的角度上看,这样才不会在一开始分析的时候就陷入代码细节; - 对于这道题,首先可以将数字分为等于0,大于0小于1,大于等于1三种情况,针对这三种情况分别进行判断即可;
- 对于每种情况,我们都要获取两个东西:
- 前n个有效位;
- 指数。
- 理清上面的思路就很好解题了,主要是代码比较繁琐;
代码实现
//从开头第一个不为0的数字找三个不为'.'的字符(如果有的话)
//超级好用to_string
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
int n;
string a,b;
bool eq=false;
string ta,tb;
string transfer(string str){
string t="0.";
if(str == "0"){
for(int i=0;i<n;i++){
t+="0";
}
t+="*10^0";
}else if(str[0] != '.'){//大于等于1的数
//寻找前面n个数字(如果有的话)
int cnt=0;
for(int i=0;i<str.size() && cnt<n;i++){
if(str[i]!='.'){
t+=str[i];
cnt++;
}
}
//判断是否找到n个
if(cnt < n){
for(int i=0;i<n-cnt;i++){
t+="0";
}
}
//然后是计算指数
int exp=0;
for(int i=0;i<str.size();i++){
if(str[i]!='.'){
exp++;
}else{
break;
}
}
t+="*10^";
t+=to_string(exp);
}else if(str[0] == '.'){//小于1大于0的数
//寻找小数点后面第一个不为0的数
int exp = 0;
int idx = 1;
for(;idx<str.size();idx++){
if(str[idx]=='0'){
exp -= 1;
}else{
break;
}
}
if(idx==str.size()){
for(int i=0;i<n;i++){
t+="0";
}
t+="*10^0";
return t;
}
//收集后面的n个数字,如果有的话
int cnt=0;
for(;idx<str.size()&&cnt<n;idx++){
t+=str[idx];
cnt++;
}
if(cnt < n){
for(int i=0;i<n-cnt;i++){
t+="0";
}
}
t+="*10^";
t+=to_string(exp);
}
return t;
}
int main(){
cin>>n>>a>>b;
//去除前导0
int idx1=0;
for(;idx1<a.size()-1;idx1++){
if(a[idx1]!='0')
break;
}
a = a.substr(idx1);
int idx2=0;
for(;idx2<b.size()-1;idx2++){
if(b[idx2]!='0')
break;
}
b = b.substr(idx2);
//0如何进行特殊处理
ta = transfer(a);
tb = transfer(b);
if(ta == tb){
printf("YES ");
cout<<ta;
}else{
printf("NO ");
cout<<ta<<" "<<tb;
}
return 0;
}
码后反思
- 这道题有一些比较变态的测试用例,比如测试点4和测试点6:
对于这种有前导0的数字要去除前导0才是!2 0012 12
注意上面的边界是//去除前导0 int idx1=0; for(;idx1<a.size()-1;idx1++){ if(a[idx1]!='0') break; } a = a.substr(idx1);
a.size()-1
,这样是绝对可行的!(可以思考一下~,无论是000,还是000.1都是能得到一个数的) - 此外,0可以表示为0.00,0.000等各种形式,需要特别判断:
if(idx==str.size()){ for(int i=0;i<n;i++){ t+="0"; } t+="*10^0"; return t; }