20200613-01 PAT 甲级试题 02 Read Number in Chinese
思路讲解
核心一: 数值的分解
1.1 大单位分解
因为需要添加 “Yi” 和 “ Wan” 两个单位,所以我的思路第一步是将其拆解成 3 个部分
//这里使用的是 C++ 所以单位转化规范一点比较好
int num_array[] = { static_cast<int>(n/100000000), //亿
static_cast<int>(n % 100000000 / 10000), //万
static_cast<int>(n % 10000)}; //个
1.2 小单位分解
经过上一步骤的分解,每个 4 位数字内部单位规律是一致的,都是 Qian Bai Shi,所以可以写一个函数进行进一步的分解,我采用的是直接分解成个位数
//数据分解为个位数
auto temp { val};
for (int i = 3; i >= 0; i--) {
ge_num[i] = temp % 10;
temp /= 10;
}
核心二: 添加 0
根据题目可知,ling 是必须要的,但不能重复出现
举例:
1 起始数字前 不能有零
2 零不能重复出现
3 特别是如 100000001 => yi Yi ling yi 万单位处为 0 则需要加上 ling
4 整数单位后的 0 可以忽略,如 1000 =>yi Qian; 100=> yi Bai; 10=> yi Shi
源码
#include <cstdio>
#include <cmath>
#include <string>
using namespace std;
string num_zn[] = {
"ling","yi","er","san","si","wu","liu","qi","ba","jiu"
};
string unit_zn[] = { "Qian", "Bai", "Shi"};
string UNIT_YI = "Yi";
string UNIT_WAN = "Wan";
//每个数字之后需要添加一个空格
string add_string(string & val) {
return val + " ";
}
//简单得到单位
string get_unit(const int & v) {
if (v < 3) {
return add_string(unit_zn[v]);
}
return "";
}
//分段处理 4 位数字
/*! * \brief digits_4 handle 4 bit number * \param val number * \param ch string * \param need_add_ling If the "ling" is not required, set the value to false * 因为这里只处理 4 位数字,并不清楚首位是否为零,由上一级指定,默认需要添加 ling */
void digits_4(const int & val, string & ch, const bool need_add_ling = true) {
string str_temp { ""};
int ge_num[4] = { 0, 0, 0, 0};
//数据分解为个位数 1234 分解 [4, 3, 2, 1]
auto temp { val};
for (int i = 3; i >= 0; i--) {
ge_num[i] = temp % 10;
temp /= 10;
}
//数据处理
int zero_count { 0};
//这样就是准确识别出 0100 1001 1010 这种
for (int i = 0; i < 4; i++) {
//0090 遇到0计1
if (ge_num[i] == 0)
zero_count++;
else {
// 1 若是首位如 100 10000 这种不需要加零 str_temp == "" && need_add_ling && zero_count != 0
// 2 中间位连续0 只写一个 ling // str_temp != "" && zero_count != 0
if (((str_temp == "" && need_add_ling) || str_temp != "")
&& zero_count != 0)
str_temp += add_string(num_zn[0]);
str_temp += add_string(num_zn[ge_num[i]]) + get_unit(i);
zero_count = 0;
}
}
ch += str_temp;
}
int main() {
long long n;
scanf("%lld", &n);
string res { ""};
if (n < 0)
res = "Fu ";
//取正整数
n = abs(n);
//值为零则输出 ling
if (n > 0) {
//分解得到数据分解成亿,万,个单位
int num_array[] = { static_cast<int>(n/100000000), //亿
static_cast<int>(n % 100000000 / 10000), //万
static_cast<int>(n % 10000)}; //个
//亿之前不需要添加 ling
string temp_str { ""};
if (num_array[0]) {
digits_4(num_array[0], temp_str, false);
temp_str += add_string(UNIT_YI);
}
res += temp_str;
//万值为0,则判断前后亿和个的值都不为0,则添加 ling,不为零则随意
// 10000001 yi Yi ling yi
temp_str = "";
if (num_array[1]) {
digits_4(num_array[1], temp_str, num_array[0] > 0);
temp_str += add_string(UNIT_WAN);
} else if (num_array[2] && num_array[0]) {
temp_str += add_string(num_zn[0]);
}
res += temp_str;
//只要之前wan的值为0, 那就不需要添加 ling, 如1, 10000001这种
temp_str = "";
if (num_array[2]) {
digits_4(num_array[2], temp_str, num_array[1] > 0);
}
res += temp_str;
} else {
res += num_zn[0];
}
printf("%s", res.c_str());
return 0;
}
推荐课程
尹成老师带你学算法
数据结构核心原理与算法应用
还没有评论,来说两句吧...