PAT甲级1060 Are They Equal

原题链接PAT甲级1060 Are They Equal
类似题目PAT甲级1073 Scientific Notation

坑点

这道题可以说是有不少坑点。
1、数据可能有前导0,即可能有数据为0000123、00000.000123、0000.0000等
2、如果数据类似于0.00000123,n为2,则应该是0.1210 ^ -5,而不是0.0010 ^ 2.
3、如果数据为0,即当给的数据类似于0、00000、0.0000,n = 4时,应该输出0.0000*10^0,指数应该也是0,不是4。所以,当数据为0时,需特判。

做法

分为两种情况讨论

一、数据含有小数点

1,先去除前导0

注意如果是数据类似于00000.000123或者0000.00000,这种情况下,需要保留小数点前一位,即处理到0.00123、0.00000即可。
代码如下

while(str[0] == '0' && str[1] != '.') str.erase(str.begin());//在数据存在小数点的情况下,不会越界

去除前导0之后,又分两种情况讨论:数据的整数部分是否是0
整数部分不是0
即类似于5674.90380
这种情况下,我们只要数据中心不含有小数点的部分,即num=5674,90380。

string num = str.substr(0,pos) + str.substr(pos+1);

之后判断num的长度与n的关系,小于n则在后面加字符0.

while(num.size() < n) num += '0';

到此就可以返回这种情况下的结果了

return "0." + num.substr(0,n) + "*10^" + to_string(pos);

整数部分是0
这种情况类似于0.0000123或者0.00000、0.123。我们需要知道小数点之后第一个不为0的字符的位置,以及中间有多少个0,这决定了转换成标准格式之后指数的大小

            for(i = pos + 1;i < str.size();i++){
    
    
                if(str[i] != '0') break;
                if(str[i] == '0') e++;
            }

至此,已经知道了这种情况之下的小数点之后有e个0,并且第一个非0字符位于 i 处。
首先判断 i 是否等于str.size(),因为如果相同,那么说明原数据小数点后面全是0,也即原数据等于0,需要特判
否则按照相应的格式输出

二、数据中心不含有小数点

这种情况比较简单,不赘述

#include <bits/stdc++.h>

using namespace std;

int n;
string getstr(string str){
    
    
    if(count(str.begin(),str.end(),'.')){
    
    //包含小数点
        while(str[0] == '0' && str[1] != '.') str.erase(str.begin());//去除前导0
        int pos = str.find('.');
        if(str[0] != '0'){
    
    //如果是小数点前面的整数部分不是0,类似 5782.XXX
            string num = str.substr(0,pos) + str.substr(pos+1);//保留去除小数点部分
            while(num.size() < n) num += '0';//如果去除小数点部分长度小于n,则在末尾加0
            return "0." + num.substr(0,n) + "*10^" + to_string(pos);//返回这种类型的结果
        }
        else{
    
    //如果整数部分是0,类似于0.18293或者0.0000332形式,注意有可能为0.000形式
            int e = 0,i;//e为从小数点开始到第一个非0字符有多少个0
            for(i = pos + 1;i < str.size();i++){
    
    
                if(str[i] != '0') break;
                if(str[i] == '0') e++;
            }
            if(i == str.size()) return "0."+string(n,'0')+"*10^0";//如果小数点后面全是0,返回相应结果
            else{
    
    //这种情况下,类似于0.0003893形式,中间有e个0,且第一个非0字符位置为i
                string num = str.substr(i);//保留从第一个非0字符开始的串
                while(num.size() < n) num += '0';//如果长度小于n,则末尾加0
                return "0."+num+"*10^"+to_string(-e);//返回结果,注意指数为-e
            }
        }
    }
    else{
    
    //不包含小数点,这种情况是最简单的
        while(str.size() > 0 && str[0] == '0') str.erase(str.begin());//去除前导0
        if(!str.size()){
    
    //如果去除前导0之后,没有元素了
            return "0."+string(n,'0')+str+"*10^0";//返回结果,注意,指数为0
        }
        if(str.size() >= n)//如果str的位数大于等于n,返回相应的结果
            return "0."+str.substr(0,n)+"*10^"+to_string(str.size());
        else{
    
    //如果str的位数小于n,返回相应的结果
            return "0."+string(n-str.size(),'0')+str+"*10^"+to_string(n);
        }
    }
}

int main()
{
    
    
    string str1,str2;
    cin>>n>>str1>>str2;
    string n1 = getstr(str1);
    string n2 = getstr(str2);
    if(n1 == n2) cout<<"YES "<<n1;
    else cout<<"NO "<<n1<<" "<<n2;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44321570/article/details/114398075