PAT-A 1060. Are They Equal (25)

一道字符串处理的题。

这题借助STL中的string处理起来要便利一些。
string有以下几点值得关注的地方:

  1. 获取字符串长度的size()/length()方法的时间复杂度为O(1)
  2. string::npos 是一个常数,本身的值为-1。由于是unsigned_int类型,因此实际上也可以认为是unsigned_int类型的最大值。它作为find()函数失配时的返回值。

题目链接在此

字符串处理的题目在我看来都不简单,思考的容量比较大,对于规律的把握十分重要,边界以及特值的处理也都要考虑周全。

这个题目的意思比较简单:比较两个数的科学记数法是否相等,然后按要求输出信息即可。

以下是我们需要思考的内容:

  1. 对于科学记数法,主要的就是找出本体和指数。故下面讨论的目标都是围绕着找指数和本体进行的。(设精度为n)
  2. 我们可以将数据分成两种情况:
    (1) 0.a1a2a3…
    (2) b1b2…bm.a1a2a3…
  3. 求指数(e):
    对于第(1)种情况:e为小数点后第一位非零数位到小数点的之间的位数
    对于第(2)种情况:若b1不为0,则e为小数点前的总位数m
  4. 求本体:
    对于第(1)种情况:其本体就是小数点后的第一位非0位往后的n位
    对于第(2)种情况:其本体就是第一位非0位往后的n位(b1不为0)
    本体位数不足n位时,用0补全。
  5. 如何判断一个数是属于以上哪种情况 以及 前导零 的问题
    拿到一个数,首先要做的应该就是去除“前导零”。
    在去除完前导零之后,通过判断第一位是否是小数点来判断是哪种情况。
    在去除前导零过程中可以拿到本体(这里拿本体的思想采用:去除非本体的部分。本体部分的位置请看4,具体操作请看6)。
  6. 拿到本体
    对于第(1)种情况:去除前导零、小数点、以及第一位非0位之前的所有数位之后的位即是本体
    对于第(2)种情况:去除前导零、小数点,剩下数位即是题目所求本体
    题目要求精度为n,只需要在上述的本体中截取前n位即可
  7. 特指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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值