洛谷P1553 数字反转(升级版)

题目

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

输入格式

一个数s

输出格式

一个数,即s的反转数

输入输出样例
输入 #1
5087462
输出 #1
2647805
输入 #2
600.084
输出 #2
6.48
输入 #3
700/27
输出 #3
7/72
输入 #4
8670%
输出 #4
768%
原题地址-> 链接

题目总结

这个题目细节很多,这是非常让人抓狂的一面。我的思路就是先分类型,对不同的类型,单独处理。这种思路简单明了,而且代码比较好写。先写出每种情况的注意事项后,再动手写代码,这是非常重要的!然后就是串中的数字内容转换为相应的数值型数字,用strtol()—>stdlib.h 。其他的也没有什么了,就是细节!细节! strtol() 具体的用法,建议直接百度,这里不再写出。这样的思路,导致代码太长,惭愧。。。凑合着看吧。。。

Code

#include<iostream>
#include<cstdio>
#include <cstdlib>
#include<cstring>
using namespace std;
void turn_str(char str[])
{
    //实现对字符串的反转
    int n=(int)strlen(str);
    int i=0,j=n-1;
    char temp;
    while(j>=i)
    {
        temp=str[i];
        str[i]=str[j];
        str[j]=temp;
        j--;
        i++;
    }
}
void _baifenshu(char str[])
{
    //百分数的整数部分反转
    char temp[22];
    int j=0;
    for (int i = 0; i < (int)strlen(str); ++i)
    {
        if (str[i]=='%')
        {
            temp[j]='\0';
            break;
        }
        temp[j++]=str[i];
    }
    turn_str(temp);
    //消除前边的无用的0,用'/'代替
    j=0;
    while(j<(int)strlen(temp))
    {
        if(temp[j]=='0')
            temp[j]='/';
        else    break;
        j++;
    };
    if(j==(int)strlen(temp))
    {
        cout << 0<< "%";
        exit(0);
    }
    for (int k = 0; k < (int)strlen(temp); ++k) {
        if(temp[k]=='/') continue;
        else cout << temp[k];
    }
    cout << "%";
}
void _xiaoshu(char str[])
{
    //小数的整数部分反转,小数部分反转
    //小数部分反转后,去掉最后的0
    //若小数部分为空,填上一个0
    bool dot_face= false;
    char zhengshu[12],xiaoshu[12];
    long int  temp_zhengshu=0,temp_xiaoshu=0;
    int n=(int)strlen(str);
    int j=0,k=0;//j->整数部分下标 k->小数部分下标
    for (int i = 0; i < n; ++i) {
        if (str[i]=='.')   {dot_face=true;i++;}
        if (!dot_face)  zhengshu[j++]=str[i];
        else    xiaoshu[k++]=str[i];
    }
    zhengshu[j]='\0';
    xiaoshu[k]='\0';
    turn_str(zhengshu);
    turn_str(xiaoshu);
    char *empty= NULL;//无用
    temp_zhengshu=strtol(zhengshu,&empty,10);
    temp_xiaoshu=strtol(xiaoshu,&empty,10);
    //注意 这里的小数不能被10整除(即:小数部分的最后不能有0)
    while(temp_xiaoshu%10==0&&temp_xiaoshu!=0)
    {
        temp_xiaoshu/=10;
    }
    cout << temp_zhengshu<< "." << temp_xiaoshu;

}
void _fenshu(char str[])
{
    //分数的分子反转,分母反转
    char fenmu[12],fenzi[12];
    int j=0,k=0;
    bool xiegang=false;//用于判断“/”是否出现
    for (int i = 0; i < (int)strlen(str); ++i)
    {
        if (str[i]=='/')
        {
            xiegang=true;
            i++;
        }
        if (!xiegang)
        {
            fenzi[j++]=str[i];
        }
        else	fenmu[k++]=str[i];
    }
    fenzi[j]='\0';
    fenmu[k]='\0';
    turn_str(fenzi);
    turn_str(fenmu);
    long int temp_fenzi,temp_fenmu;
    char *empty=NULL;//empty指针是一个无用的指针,完全是为了用strtol()
    temp_fenmu=strtol(fenmu,&empty,10);
    temp_fenzi=strtol(fenzi,&empty,10);
    cout << temp_fenzi << "/" << temp_fenmu;
}
void _zhengshu(char str[]){
    int n=(int)strlen(str);
    turn_str(str);
    int j=0;
    while(j<n)
    {
        if(str[j]!='0')
            break;
        else    str[j]='/';
        j++;
    };
    if(j==n)
    {
        cout << 0;
        exit(0);
    }
    for (int i = 0; i < n ; i++) {
        if(str[i]=='/') continue;
        else cout << str[i];
    }
}
int main(int argc, char const *argv[])
{
    bool dot=false,fenshu=false,baifenshu=false;
    char str[24];
    gets(str);
    for (int i = 0; i < (int)strlen(str); ++i)
    {
        if (str[i]=='.')
        {
            dot=true;
            break;
        }
        if (str[i]=='/')
        {
            fenshu=true;
        }
        if (str[i]=='%')
        {
            baifenshu=true;
        }
    }
    if (dot)
    {
        _xiaoshu(str);
    }
    else if (fenshu)//分数的分子反转,分母反转
    {
        _fenshu(str);
    }
    else if (baifenshu)//百分数的整数反转
    {
        _baifenshu(str);
    }
    else//整数
    {
        //鉴于str中对应的整数太大,所以逆序输出
        _zhengshu(str);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值