20200613-01 PAT 甲级试题 02 Read Number in Chinese

ゝ一纸荒年。 2023-02-17 08:54 103阅读 0赞

思路讲解

核心一: 数值的分解

1.1 大单位分解

因为需要添加 “Yi” 和 “ Wan” 两个单位,所以我的思路第一步是将其拆解成 3 个部分

  1. //这里使用的是 C++ 所以单位转化规范一点比较好
  2. int num_array[] = { static_cast<int>(n/100000000), //亿
  3. static_cast<int>(n % 100000000 / 10000), //万
  4. static_cast<int>(n % 10000)}; //个
1.2 小单位分解

经过上一步骤的分解,每个 4 位数字内部单位规律是一致的,都是 Qian Bai Shi,所以可以写一个函数进行进一步的分解,我采用的是直接分解成个位数

  1. //数据分解为个位数
  2. auto temp { val};
  3. for (int i = 3; i >= 0; i--) {
  4. ge_num[i] = temp % 10;
  5. temp /= 10;
  6. }

核心二: 添加 0

根据题目可知,ling 是必须要的,但不能重复出现
举例:
1 起始数字前 不能有零
2 零不能重复出现
3 特别是如 100000001 => yi Yi ling yi 万单位处为 0 则需要加上 ling
4 整数单位后的 0 可以忽略,如 1000 =>yi Qian; 100=> yi Bai; 10=> yi Shi

源码

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <string>
  4. using namespace std;
  5. string num_zn[] = {
  6. "ling","yi","er","san","si","wu","liu","qi","ba","jiu"
  7. };
  8. string unit_zn[] = { "Qian", "Bai", "Shi"};
  9. string UNIT_YI = "Yi";
  10. string UNIT_WAN = "Wan";
  11. //每个数字之后需要添加一个空格
  12. string add_string(string & val) {
  13. return val + " ";
  14. }
  15. //简单得到单位
  16. string get_unit(const int & v) {
  17. if (v < 3) {
  18. return add_string(unit_zn[v]);
  19. }
  20. return "";
  21. }
  22. //分段处理 4 位数字
  23. /*! * \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 */
  24. void digits_4(const int & val, string & ch, const bool need_add_ling = true) {
  25. string str_temp { ""};
  26. int ge_num[4] = { 0, 0, 0, 0};
  27. //数据分解为个位数 1234 分解 [4, 3, 2, 1]
  28. auto temp { val};
  29. for (int i = 3; i >= 0; i--) {
  30. ge_num[i] = temp % 10;
  31. temp /= 10;
  32. }
  33. //数据处理
  34. int zero_count { 0};
  35. //这样就是准确识别出 0100 1001 1010 这种
  36. for (int i = 0; i < 4; i++) {
  37. //0090 遇到0计1
  38. if (ge_num[i] == 0)
  39. zero_count++;
  40. else {
  41. // 1 若是首位如 100 10000 这种不需要加零 str_temp == "" && need_add_ling && zero_count != 0
  42. // 2 中间位连续0 只写一个 ling // str_temp != "" && zero_count != 0
  43. if (((str_temp == "" && need_add_ling) || str_temp != "")
  44. && zero_count != 0)
  45. str_temp += add_string(num_zn[0]);
  46. str_temp += add_string(num_zn[ge_num[i]]) + get_unit(i);
  47. zero_count = 0;
  48. }
  49. }
  50. ch += str_temp;
  51. }
  52. int main() {
  53. long long n;
  54. scanf("%lld", &n);
  55. string res { ""};
  56. if (n < 0)
  57. res = "Fu ";
  58. //取正整数
  59. n = abs(n);
  60. //值为零则输出 ling
  61. if (n > 0) {
  62. //分解得到数据分解成亿,万,个单位
  63. int num_array[] = { static_cast<int>(n/100000000), //亿
  64. static_cast<int>(n % 100000000 / 10000), //万
  65. static_cast<int>(n % 10000)}; //个
  66. //亿之前不需要添加 ling
  67. string temp_str { ""};
  68. if (num_array[0]) {
  69. digits_4(num_array[0], temp_str, false);
  70. temp_str += add_string(UNIT_YI);
  71. }
  72. res += temp_str;
  73. //万值为0,则判断前后亿和个的值都不为0,则添加 ling,不为零则随意
  74. // 10000001 yi Yi ling yi
  75. temp_str = "";
  76. if (num_array[1]) {
  77. digits_4(num_array[1], temp_str, num_array[0] > 0);
  78. temp_str += add_string(UNIT_WAN);
  79. } else if (num_array[2] && num_array[0]) {
  80. temp_str += add_string(num_zn[0]);
  81. }
  82. res += temp_str;
  83. //只要之前wan的值为0, 那就不需要添加 ling, 如1, 10000001这种
  84. temp_str = "";
  85. if (num_array[2]) {
  86. digits_4(num_array[2], temp_str, num_array[1] > 0);
  87. }
  88. res += temp_str;
  89. } else {
  90. res += num_zn[0];
  91. }
  92. printf("%s", res.c_str());
  93. return 0;
  94. }

推荐课程

尹成老师带你学算法

数据结构核心原理与算法应用

发表评论

表情:
评论列表 (有 0 条评论,103人围观)

还没有评论,来说两句吧...

相关阅读