目录概要

一 ，模拟题介绍

何为模拟题？

【PAT 甲级 1082】 Read Number in Chinese (25分)

字符串处理问题很能体现代码能力的一种题型，一般实现逻辑会非常麻烦，而且可能



二 ，题目描述

PAT 甲级 1082 Read Number in Chinese (25分)

Given an integer with no more than 9 digits, you are supposed toread it in the
traditional Chinese way. Output Fu first if it is negative. For example, -12345
6789 is read as Fu yi Yi er Qian san Bai si Shiwu Wan liu Qian qi Bai ba Shi jiu.
Note: zero (ling) must be handled correctly according to the Chinese tradition.
For example 100800 is yi Shi Wan ling ba Bai


Input Specification:

Each input file contains one test case, which gives an  integer with no more than 9 digits.


Output Specification:

For each test case, print in a line the Chinese way of reading the number. The
characters are separated by a space and there must be no extra space at the
end of the line.


Sample Input 1:

-123456789


Sample Output 1:

Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu


Sample Input 2:

100800


Sample Output 2:

yi Shi Wan ling ba Bai


三 ，题意简介

-123456789
Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu

100800
yi Shi Wan ling ba Bai

（注意：题目给的例子是远远不够的）

四 ， 题解思路

4.1 题解说明

(前提是自己认认真真做的，切记不要一上手即百度,)

4.2 题解初思路

123456789
yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu

char num[10][5] = {“ling”, “yi”, “er”, “san”, “si”, “wu”, “liu”, “qi”, “ba”, “jiu”};
char unit[10][5] = {"" ,"",“Shi”, “Bai”, “Qian”, “Wan”,“Shi”, “Bai”, “Qian”,“Yi”};
char s[12] = {‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’ };

int len = strlen(s);
for (int i = 0; i <= strlen(s) - 1; i++)
{
if (i != strlen(s) - 1)
printf("%s %s", num[s[i] - '0'], unit[len - i]);
else {
printf("%s", num[s[i] - '0']);
}


4.3 解题讨论的情况

102000783
yi Yi ling er Bai Wan ling qi Bai ba Shi san

100000007
yi Yi ling qi

100000600
yi Yi ling liu Bai

100024008
yi Yi ling er Wan si Qian ling ba

103040760
yi Yi ling san Bai ling si Wan ling qi Bai liu Shi

1. 末尾如果全部是0，比如100007000，只会打印qi Bai末尾不能有多余空格

2. 如果0在中间即100000600，这里是不会打印Wan的

3. 什么情况下又会打印Wan呢？且又打印0呢？ 比如102000783

4. 连续的 0 又如何处理?

5. 是否需要打印空格，什么情况下打印空格？等等之类的各种细节

6. 你考虑到这些问题啦吗?

#include <cstdio>
#include <cstring>

char num[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
char unit[10][5] = {"" ,"","Shi", "Bai", "Qian", "","Shi", "Bai", "Qian","Yi"};//这里我把“Wan”去掉啦，因为不一定会打印Wan,刚才的例子可以证明

char s[12];
//我这里先考虑正整数的情况(包括0)
int main()
{
scanf("%s", &s);
//---------------------------------------------
int k = strlen(s) - 1;//
for (int i = strlen(s) - 1; i >= 0; i--)
if (s[i] != '0'){
k = i;
break;
}
//k表示处理掉情况1 ，末尾有连续 0
//------------------------------------------------
int len = strlen(s);//表示长度
bool falg = false;//来判断是否会打印Wan
//--------------------------------------

//------------------------------------------------------------------
if (len == 9)  { //表示9位，最高位为亿
if (s[1] != '0' || s[2] != '0' || s[3] != '0' || s[4] != '0')
falg = true;//如果在千万，百万，十万以及个万位不为0，说明是需要打印Wan的
for (int i = 0; i <= k; i++)//从0开始遍历到k
{
if (s[i] == '0' && s[i + 1] != '0')//连续0的处理情况
{
if (i != 4)//假如个位万位为0，千位不为为0，那么是不需要打ling的，举例104003007
printf("ling ");
}
if (s[i] != '0')
{
if(i == k && k < len - 1)//如果k不在最后一个位置，我们是需要打印它的单位的，举例10400300，最后打印 san Qian
printf("%s %s", num[s[i] - '0'], unit[len - i]);
else if ((i == k && k == len - 1) || i == 4)
{//如果k在最后一个位置，我们是不需要打印它的单位的，举例104000003，最后打印san
printf("%s", num[s[i] - '0']);
if (i == 4)//当然这里还需考虑个位万位置不为0的情况，那么我们需要加空格的，比如104033007
printf(" ");
}
else//正常情况下正常打印即可
printf("%s %s ", num[s[i] - '0'], unit[len - i]);
}
if (i == 4 && falg)//Wan打印的情况
printf("Wan ");
}
}

//---------------------------------------------------------------
else if (len >= 5)//这里表示长度大于或等于万位 但小于 亿位
{//代码部分基本一致，主要是Wan打印的处理不同而已
for (int i = 0; i < (len - 4); i++)
{
if (s[i] != '0') {
falg = true;
break;
}
}
for (int i = 0; i <= k; i++)
{
if (s[i] == '0' && s[i + 1] != '0')
{
if (i != len - 5)
printf("ling ");
}
if (s[i] != '0')
{
if(i == k && k < len - 1)
printf("%s %s", num[s[i] - '0'], unit[len - i]);
else if ((i == k && k == len - 1) || i == len - 5)
{
printf("%s", num[s[i] - '0']);
if (i == len - 5)
printf(" ");
}
else
printf("%s %s ", num[s[i] - '0'], unit[len - i]);
}
if (i == len - 5 && falg)
printf("Wan ");
}
}
//-------------------------------------------------------------

else {//长度小于或等于千位的情况
//千位情况不用考虑Wan，只需考虑连续0 以及k的位置
for (int i = 0; i <= k; i++)
{
if (s[i] == '0' && s[i + 1] != '0')
{
if (k == 0)
printf("ling");//如果正整数位0，那么末尾是不需要空格的，处理0的情况
else printf("ling ");

}
if (s[i] != '0')
{
if(i == k && k < len - 1)
printf("%s %s", num[s[i] - '0'], unit[len - i]);
else if (i == k && k == len - 1)
{
printf("%s", num[s[i] - '0']);
}
else
printf("%s %s ", num[s[i] - '0'], unit[len - i]);
}
}
}
return 0;
}


五 ，题解C++ 代码

代码已Accept！！！

#include <cstdio>
#include <cstring>

char num[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
char unit[10][5] = {"" ,"","Shi", "Bai", "Qian", "","Shi", "Bai", "Qian","Yi"};
char s[12];

//本题考查的主要问题在0的处理
int main()
{
scanf("%s", &s);
//分两种情况讨论
if (s[0] == '-')
{//负数的情况要从1开始的，后面相应的位置要更该，总之要小心喲
printf("Fu ");

int k = strlen(s) - 1;
for (int i = strlen(s) - 1; i >= 1; i--)
if (s[i] != '0'){
k = i;
break;
}
int len = strlen(s) - 1;//注意长度要减1，减去负号
bool falg = false;
//--------------------------------------

if (len == 9) {
if (s[2] != '0' || s[3] != '0' || s[4] != '0' || s[5] != '0')
falg = true;
for (int i = 1; i <= k; i++)//从1开始
{
if (s[i] == '0' && s[i + 1] != '0')
{
if (i != 5)
printf("ling ");
}
if (s[i] != '0')
{
if(i == k && k < strlen(s) - 1)
printf("%s %s", num[s[i] - '0'], unit[len - i + 1]);
else if ((i == k && k == strlen(s) - 1) || i == 5)
{
printf("%s", num[s[i] - '0']);
if (i == 5)
printf(" ");
}
else
printf("%s %s ", num[s[i] - '0'], unit[len - i + 1]);
}
if (i == 5 && falg)
printf("Wan ");
}
}

//--------------------------------------------------------------

else if (len >= 5)
{
for (int i = 1; i < (len - 3); i++)
{
if (s[i] != '0') {
falg = true;
break;
}
}
for (int i = 1; i <= k; i++)
{
if (s[i] == '0' && s[i + 1] != '0')
{
if (i != len - 4)
printf("ling ");
}
if (s[i] != '0')
{
if(i == k && k < strlen(s) - 1)
printf("%s %s", num[s[i] - '0'], unit[len - i + 1]);
else if ((i == k && k == strlen(s) - 1) || i == len - 4)
{
printf("%s", num[s[i] - '0']);
if (i == len - 4)
printf(" ");
}
else
printf("%s %s ", num[s[i] - '0'], unit[len - i + 1]);
}
if (i == len - 4 && falg)
printf("Wan ");
}
}
//------------------------------------------------------
else {

for (int i = 1; i <= k; i++)
{
if (s[i] == '0' && s[i + 1] != '0')
{
printf("ling ");
}
if (s[i] != '0')
{
if(i == k && k < strlen(s) - 1)
printf("%s %s", num[s[i] - '0'], unit[len - i + 1]);
else if (i == k && k == strlen(s) - 1)
{
printf("%s", num[s[i] - '0']);
}
else
printf("%s %s ", num[s[i] - '0'], unit[len - i + 1]);
}
}
}
}
//------------------------------------------------------
//------------------------------------------------------
//------------------------------------------------------
else//正数
{
//---------------------------------------
int k = strlen(s) - 1;
for (int i = strlen(s) - 1; i >= 0; i--)
if (s[i] != '0'){
k = i;
break;
}
int len = strlen(s);
bool falg = false;
//--------------------------------------

if (len == 9) {
if (s[1] != '0' || s[2] != '0' || s[3] != '0' || s[4] != '0')
falg = true;
for (int i = 0; i <= k; i++)
{
if (s[i] == '0' && s[i + 1] != '0')
{
if (i != 4)
printf("ling ");
}
if (s[i] != '0')
{
if(i == k && k < len - 1)
printf("%s %s", num[s[i] - '0'], unit[len - i]);
else if ((i == k && k == len - 1) || i == 4)
{
printf("%s", num[s[i] - '0']);
if (i == 4)
printf(" ");
}
else
printf("%s %s ", num[s[i] - '0'], unit[len - i]);
}
if (i == 4 && falg)
printf("Wan ");
}
}

//---------------------------------------------------------------------
else if (len >= 5)
{
for (int i = 0; i < (len - 4); i++)
{
if (s[i] != '0') {
falg = true;
break;
}
}

for (int i = 0; i <= k; i++)
{
if (s[i] == '0' && s[i + 1] != '0')
{
if (i != len - 5)
printf("ling ");
}
if (s[i] != '0')
{
if(i == k && k < len - 1)
printf("%s %s", num[s[i] - '0'], unit[len - i]);
else if ((i == k && k == len - 1) || i == len - 5)
{
printf("%s", num[s[i] - '0']);
if (i == len - 5)
printf(" ");
}
else
printf("%s %s ", num[s[i] - '0'], unit[len - i]);
}
if (i == len - 5 && falg)
printf("Wan ");
}
}
//------------------------------------------------------
else {

for (int i = 0; i <= k; i++)
{
if (s[i] == '0' && s[i + 1] != '0')
{
if (k == 0)
printf("ling");
else printf("ling ");

}
if (s[i] != '0')
{
if(i == k && k < len - 1)
printf("%s %s", num[s[i] - '0'], unit[len - i]);
else if (i == k && k == len - 1)
{
printf("%s", num[s[i] - '0']);
}
else
printf("%s %s ", num[s[i] - '0'], unit[len - i]);
}
}
}
}
return 0;
}


六，官方题解(算法笔记)

官方题解代码比较好理解，这里不做过多的注释与说明
(其实看完我写的题解，基本即可理解）

#include <cstdio>
#include <cstring>

char num[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
char wei[5][5] = {"Shi", "Bai", "Qian", "Wan", "Yi"};
int main()
{
char str[15];
gets(str);

int len = strlen(str);
int left = 0, right = len - 1;
if (str[0] == '-') {
printf("Fu");
left++;
}
while (left + 4 <= right)
{
right -= 4;
}
while (left < len)
{
bool flag = false;
bool isPrint = false;
while (left <= right)
{
if (left > 0 && str[left] == 0)
flag = true;
else {
if (flag == true) {
printf(" ling");
flag = false;
}
if (left > 0) printf(" ");
printf("%s", num[str[left] - '0']);
isPrint = true;
if (left != right) {
printf(" %s", wei[right - left - 1]);
}
}
left++;
}
if (isPrint == true && right != len - 1)
printf(" %s", wei[(len - 1 - right) / 4 + 2]);
right += 4;
}
return 0;
}

08-20

10-17 676
12-24 212
06-26 9万+
07-19