• P1553 数字反转(升级版)—— copy,reverse,find,substr,erase 的使用


    题目描述

    给定一个数,请将该数各个位上数字反转得到一个新数。

    这次与 NOIp2011 普及组第一题不同的是:这个数可以是小数,分数,百分数,整数。整数反转是将所有数位对调;小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分;分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母;百分数的分子一定是整数,百分数只改变数字部分。整数新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零;小数新数的末尾不为 0(除非小数部分除了 0 没有别的数,那么只保留 1 个 0 );分数不约分,分子和分母都不是小数(约分滴童鞋抱歉了,不能过哦。输入数据保证分母不为 0 ),本次没有负数。

    输入格式

    一个数 s

    输出格式

    一个数,即s的反转数

    输入输出样例

    输入 
    5087462
    输出 
    2647805
    输入 
    600.084
    输出 
    6.48
    输入
    700/27
    输出 
    7/72
    输入 
    8670%
    输出 
    768%

    说明/提示

    所有数据:25% s 是整数,不大于 20 位

    25% s 是小数,整数部分和小数部分均不大于 10 位

    25% s 是分数,分子和分母均不大于 10 位

    25% s 是百分数,分子不大于 19 位

    (20个数据)

    思路:

    这道题就是一道细节题,很坑,稍微不小心就会出错。
    分为两个大部分
    1、整数情况:去除反转后的前导零后反向输出
    2、非整数情况(百分数、分数、小数):
    a.百分数:先忽略掉百分号,去除数字部分反转后的前导零后,反向输出数字部分,再输出百分号
    b.分数:分子部分,去除反转后的前导零,再反向输出分子部分;输出分数线;分母部分,去除反转后的前导零,再反向输出分母部分。
    c.小数:整数部分,去除反转后的前导零,再反向输出整数部分;输出小数点;小数部分,去除反向后的后导零,再反向输出小数部分。

    不用考虑 0098 类型的整数以及 0.8900类型的小数。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    string delzero(string a){
        int k=0;
        string tem;
    
        //确定首个不是 0 的数字的索引
        while(k<a.size()&&a[k]=='0'){
            k++;
        }
        if(k==a.size()){//整数且全为 0
            return "0";
        }
        if(a[k]=='.'||a[k]=='/'||a[k]=='%'){//不是整数,但整数部分全为 0
            tem+="0";
        }
        for(k;k<a.size();k++){//拼接上剩余部分
            tem+=a[k];
        }
        return tem;
    }
    
    int main(){
        string a;
        cin>>a;
        string tem="";
        int choise=0,pos=-1;
        if(a.find(".")!=a.npos){
            choise=1;
            pos=a.find(".");
        }
        else if(a.find("/")!=a.npos){
            choise=2;
            pos=a.find("/");
        }
        else if(a.find("%")!=a.npos){
            choise=3;
        }
        int k=0;
        switch (choise){
            case 0://整数
                reverse(a.begin(),a.end());
                a=delzero(a);
                break;
           case 1://小数
            case 2://分数
                 //处理后半部分 
                    tem=a.substr(pos+1);
                 tem=delzero(tem);
                 reverse(tem.begin(),tem.end());
                 tem=delzero(tem);
                 copy(tem.begin(),tem.end(),a.begin()+pos+1);
                 a.erase(a.begin()+pos+tem.size()+1,a.end());
                 //处理前半部分 
                   reverse(a.begin(),a.begin()+pos);
                 a=delzero(a);
                 break;
            case 3://百分数
                  reverse(a.begin(),a.end()-1);
                a=delzero(a);
                break;
        }
        cout<<a;    
    } 

    遇到问题:

    1. copy(tem.begin(),tem.end(),a.begin()); 复制区间是左闭右开的,即将 tem[begin,end),复制到 a[a.begin(),tem.size());需注意,copy() 的形参为迭代器,不能直接写索引下标。头文件 #include<algorithm>
    2. switch case 语句中尽量不要声明临时变量。
    3. reverse(s.begin(),s.end()); 可是实现字符串的翻转。头文件 #include<algorithm>
    4. string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记 npos(s.find("a"))!=s.npos)。
    5. a.substr(0,pos); 用于提取 a 中[0,pos)范围内的字符。
    6. a.erase(a.begin(),a.end()); 传入两个迭代器 a.begin(),a.end(),清除[a.begin(),a.end())范围内的字符。

     

  • 相关阅读:
    Pycharm如何自动换行
    Android逆向基础
    动态调试ELF文件Crackme
    用Hash 算法给payload瘦身
    010 editor手写pe文件
    win脱壳_压缩壳_aspack
    WannaCrypt0r分析报告
    JVM内存分区
    java设计模式(模板方法模式)
    es6
  • 原文地址:https://www.cnblogs.com/bjxqmy/p/12194412.html
Copyright © 2020-2023  润新知