输入一个整数(位数不超过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,吐槽完毕。
如有问题,欢迎提出。