【PTA基础编程题目集(C语言)】7-23 币值转换

输入一个整数(位数不超过9位)代表一个人民币值(单位为元),请转换成财务要求的大写中文格式。如23108元,转换后变成“贰万叁仟壹百零捌”元。为了简化输出,用小写英文字母a-j顺序代表大写数字0-9,用S、B、Q、W、Y分别代表拾、百、仟、万、亿。于是23108元应被转换输出为“cWdQbBai”元。

输入格式:

输入在一行中给出一个不超过9位的非负整数。

输出格式:

在一行中输出转换后的结果。注意“零”的用法必须符合中文习惯。

输入样例1:

813227345

输出样例1:

iYbQdBcScWhQdBeSf

输入样例2:

6900

输出样例2:

gQjB

#include <stdio.h>
#include <string.h>
#include <math.h>
void read_num(char num) //数字大写输出
{
    printf("%c", 'a' + (num - '0'));
    return;
}
void read_danwei(int danwei) //单位大写输出
{
    switch (danwei)
    {
    case 1:break;
    case 10:printf("S"); break;
    case 100:printf("B"); break;
    case 1000:printf("Q"); break;
    case 10000:printf("W"); break;
    }
    return;
}
void buling(char num[], int weishu) //补0,不足四位补成四位,如23->0023
{
    int i;
    if (weishu != 4)
    {
        for (i = weishu - 1; i > -1; i--) //原数字右移
        {
            num[i + (4 - weishu)] = num[i];
        }
        for (i = 0; i < 4 - weishu; i++) //补0
        {
            num[i] = '0';
        }
    }
}
void read_four(char num[], int weishu) //每四位级大写输出
{
    int i, temp = 0;
    int zero_place = -1, danwei, nozero_place = -1, zero2_place = -1;
    buling(num, weishu); //补0
    for (i = 0; i < 4; i++) //统计0的个数
    {
        if ('0' == num[i])
        {
            temp++;
        }
    }
    switch (temp)
    {
    case 0: //没有0,直接读
        danwei = (int)pow(10, weishu - 1);
        for (i = 0; i < weishu; i++)
        {
            read_num(num[i]);
            read_danwei(danwei);
            danwei /= 10;
        }
        break;
    case 1: //有一个0,考虑0在最前面
        for (i = 0; i < weishu; i++)
        {
            if ('0' == num[i]) //记录唯一0的位置
            {
                zero_place = i;
                break;
            }
        }
        danwei = 1000;
        for (i = 0; i < 4; i++)
        {
            if (0 == zero_place) //情况0XXX:如果0是首个数字,不读,跳过本次循环
            {
                zero_place = -1;
                danwei /= 10;
                continue;
            }
            if (3 == zero_place) //情况XXX0:如果0是最后一个数字,未读到0就正常输出
            {
                if ('0' != num[i])
                {
                    read_num(num[i]);
                    read_danwei(danwei);
                }
                danwei /= 10;
            }
            else { //情况X0XX和XX0X:0只读数字不读单位
                if ('0' == num[i])
                {
                    printf("a");
                    danwei /= 10;
                }
                else {
                    read_num(num[i]);
                    read_danwei(danwei);
                    danwei /= 10;
                }
            }
        }
        break;
    case 2:
        for (i = 0; i < 4; i++) //获取两个0的位置
        {
            if ('0' == num[i] && -1 == zero_place)
                zero_place = i + 1;
            else if ('0' == num[i])
                zero2_place = i + 1;
        }
        if (1 == zero_place) //根据两个0的位置分不同情况
        {
            switch (zero2_place)
            {
            case 2:
                danwei = 10;
                for (i = 2; i < 4; i++)
                {
                    read_num(num[i]);
                    read_danwei(danwei);
                    danwei /= 10;
                }
                break;
            case 3:
                read_num(num[1]);
                printf("Ba");
                read_num(num[3]);
                break;
            case 4:
                read_num(num[1]);
                printf("B");
                read_num(num[2]);
                printf("S");
                break;
            }
        }
        else if (2 == zero_place)
        {
            if (3 == zero2_place)
            {
                read_num(num[0]);
                read_danwei(1000);
                read_num('0');
                read_num(num[3]);
            }
            else {
                read_num(num[0]);
                read_danwei(1000);
                read_num('0');
                read_num(num[2]);
                read_danwei(10);
            }
        }
        else {
            danwei = 1000;
            for (i = 0; i < 2; i++)
            {
                read_num(num[i]);
                read_danwei(danwei);
                danwei /= 10;
            }
        }
        break;
    case 3:
        for (i = 0; i < 4; i++)
        {
            if ('0' != num[i])
            {
                nozero_place = i;
                break;
            }
        }
        if (2 == nozero_place && '1' == num[2])
            ;
        else
            read_num(num[nozero_place]);
        danwei = pow(10, 3 - nozero_place);
        read_danwei(danwei);
        break;
    case 4:
        printf("a");
        break;
    }
}
int main()
{
    char num[10] = { '\0' }; //储存给定数字字符串
    char num_temp[5] = { '\0' }; //将数字分为三个数位级(亿级,万级,个级),每级四位单独储存,每级读法大部分相同
    scanf("%s", num);
    int weishu, temp;
    weishu = strlen(num);
    int i, j;
    if (1 <= weishu && weishu <= 4)
        read_four(num, weishu); //四位及以内直接读
    else if (5 <= weishu && weishu <= 8)
    {
        for (i = 0; i < weishu - 4; i++)
        {
            num_temp[i] = num[i];
        }
        weishu = strlen(num_temp);
        read_four(num_temp, weishu); //先读万级数字,末尾加“W”
        printf("W");
        int ge_four = 0; //八位及以内需考虑个级四个数字是否均为0
        temp = 0;
        for (i = 1; i < 5; i++) //检查个级四个数字
        {
            if ('0' == num[i])
                temp++;
        }
        if (4 == temp)
            ge_four++; //符合条件,加入状态“个级四个数字均为0”,个级不用读
        if (1 != ge_four)
        {
            for (i = weishu, j = 0; i < weishu + 4; i++, j++) //否则取出个级四位数字
            {
                num_temp[j] = num[i];
            }
            int sum = 0;
            for (i = 0; i < 4; i++) //计算个级数值大小,小于1000要读一个0
            {
                sum += (num_temp[i] - 48) * pow(10, 3 - i);
            }
            if (sum <= 999)
                printf("a");
            read_four(num_temp, 4); //剩余部分正常读
        }
    }
    else { //九位数字,最高达亿级
        read_num(num[0]);
        printf("Y"); //亿级直接读
        temp = 0;
        for (i = 1; i < 5; i++)
        {
            if ('0' == num[i])
                temp++;
        }
        int wan_four = 0, ge_four = 0; //相同套路,判断“万级均为0”或“个级均为0”状态是否存在
        if (4 == temp)
        {
            wan_four = 1;
            for (i = 5; i < 9; i++)
            {
                if ('0' == num[i])
                    temp++;
            }
            if (8 == temp)
                ge_four = 1;
        }  //根据状态,接下来分多种情况讨论,八个0的情况直接不读
        if (1 != wan_four && 1 != ge_four)
        {
            for (i = 1, j = 0; i < 5; i++, j++)
            {
                num_temp[j] = num[i];
            }
            int sum = 0;
            for (i = 0; i < 4; i++)
            {
                sum += (num_temp[i] - 48) * pow(10, 3 - i);
            }
            if (sum <= 999)
                printf("a");
            read_four(num_temp, 4);
            printf("W");
            for (i = 5, j = 0; i < 9; i++, j++)
            {
                num_temp[j] = num[i];
            }
            for (i = 0; i < 4; i++)
            {
                sum += (num_temp[i] - 48) * pow(10, 3 - i);
            }
            if (sum <= 999)
                printf("a");
            read_four(num_temp, 4);
        }
        else if (1 != wan_four && 1 == ge_four)
        {
            for (i = 1, j = 0; i < 5; i++, j++)
            {
                num_temp[j] = num[i];
            }
            read_four(num_temp, 4);
            printf("W");
        }
        else if (1 == wan_four && 1 != ge_four)
        {
            printf("a");
            for (i = 5, j = 0; i < 9; i++, j++)
            {
                num_temp[j] = num[i];
            }
            read_four(num_temp, 4);
        }
    }
    return 0;
}

 注意事项:

注意“零”的用法必须符合中文习惯。本题最大难点,因为情况有很多,每种可能的情况都需要考虑到,需要用各种例子试错。

鄙人的想法是将给定数字分成1-4-4三部分(如果能),先写出能正确读出个级四位数字的函数,万级四位数字沿用上述函数,在此基础上考虑特殊情况,亿级同理。

解题耗时较长,容我吐槽一下,测试点2“不超过亿,中间连续多0”一直“答案错误”卡了超级久,要是PTA能说明本次测试用的数据就好了,中间连续多0的情况有很多,一时半会想不到是什么情况出错了,只能一个一个排除!OK,吐槽完毕。

如有问题,欢迎提出。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花辞树dor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值