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
#include
#include
using namespace std;
string delzero(string a){
    int k=0;
    string tem;
    while(k'0'){
        k++;
    }
    if(k==a.size()){
        return "0";
    }
    if(a[k]=='.'||a[k]=='/'||a[k]=='%'){
        tem+="0";
    }
    for(k;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:
            reverse(a.begin(),a.begin()+pos);
            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());
             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
  2. switch case 语句中尽量不要声明临时变量。
  3. reverse(s.begin(),s.end()); 可是实现字符串的翻转。头文件 #include
  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())范围内的字符。

 

你可能感兴趣的:(P1553 数字反转(升级版)(copy(),reverse(),find(),substr(),erase()))