整数转化为中文数字表达

时间:2021-01-24 06:55:06

问题是一个整数(范围1~99999999),转化为合乎日常习惯的中文数字表达。

第一步先把这个整数拆开来,如12345拆成{5,4,3,2,1},倒序是因为。。。方便(懒):

1 local function numToTbl(num)
2 local ret = {}
3 while num > 0 do
4 table.insert(ret, num%10)
5 num = math.floor(num / 10)
6 end
7 return ret
8 end
9 ed.numToTbl = numToTbl

第二步从后往前遍历,把数字的中文表达和相应的倍数表达加上,如1 2 3 4 5 = “一”+“万”+“二”+“千”+“三”+“百”+“四”+“千”+“五”+“”(个位数就让它的倍数为空字符串):

 1 local function numToChineseStr(num)
2 local digits = {
3 [0] = "",
4 [1] = "",
5 [2] = "",
6 [3] = "",
7 [4] = "",
8 [5] = "",
9 [6] = "",
10 [7] = "",
11 [8] = "",
12 [9] = "",
13 }
14
15 local hundreds = {
16 [0] = "",
17 [1] = "",
18 [2] = "",
19 [3] = "",
20 [4] = "",
21 [5] = "十万",
22 [6] = "百万",
23 [7] = "千万",
24 }
25
26 local ret = ""
27
28 for i = #numTbl, 1, -1 do
29 local digit = numTbl[i]
30 ret = ret .. digits[digit] .. hundreds[i-1]
31 end
32
33 return ret
34 end
35 ed.numToChineseStr = numToChineseStr

这么简单显然不可能。。。中文里有一些约定俗成的表达方法,如10、100101、100000等,下面再进行改进: 

 1 local function numToChineseStr(num)
2 local digits = {
3 [0] = "",
4 [1] = "",
5 [2] = "",
6 [3] = "",
7 [4] = "",
8 [5] = "",
9 [6] = "",
10 [7] = "",
11 [8] = "",
12 [9] = "",
13 }
14
15 local hundreds = {
16 [0] = "",
17 [1] = "",
18 [2] = "",
19 [3] = "",
20 [4] = "",
21 [5] = "十万",
22 [6] = "百万",
23 [7] = "千万",
24 }
25
26 local ret = ""
27
28 local lastNotZero = nil
29 local numTbl = ed.numToTbl(num)
30 -- 第一遍循环先从后往前找到第一个不是0的位
31 for i = 1, #numTbl do
32 local digit = numTbl[i]
33 if digit ~= 0 then
34 lastNotZero = i
35 break
36 end
37 end
38
39 local lastZero = nil
40 for i = #numTbl, 1, -1 do
41 local digit = numTbl[i]
42 if digit == 0 then
43 -- 处理零或连续多个零的情况,或最后一个零
44 if (lastZero and lastZero == i+1) or i == 1 then
45
46 elseif lastNotZero < i then -- 判断从第i位起往后是不是都是零
47 ret = ret .. digits[digit]
48 end
49 lastZero = i
50 elseif digit == 1 and (i == 2 or i == 6) then
51 -- 处理10~19 和 100101这种情况
52 ret = ret .. hundreds[i-1]
53 else
54 ret = ret .. digits[digit] .. hundreds[i-1]
55 end
56 end
57
58 return ret
59 end
60 ed.numToChineseStr = numToChineseStr
61
62 local function checkChineseStr(num, correctStr)
63 local chineseStr = ed.numToChineseStr(num)
64 print(chineseStr)
65 print(correctStr)
66 if chineseStr == correctStr then
67 print(num .. " correct")
68 else
69 print(num .. " wrong")
70 end
71 print("")
72 end
73 ed.checkChineseStr = checkChineseStr
74
75 ed.checkChineseStr(1, "")
76 ed.checkChineseStr(12345, "一万二千三百四十五")
77 ed.checkChineseStr(50040030, "五千万零四万零三十")
78 ed.checkChineseStr(10, "")
79 ed.checkChineseStr(11, "十一")
80 ed.checkChineseStr(19, "十九")
81 ed.checkChineseStr(10101, "一万零一百零一")
82 ed.checkChineseStr(100101, "十万零一百零一")
83 ed.checkChineseStr(1000101, "一百万零一百零一")
84 ed.checkChineseStr(100000, "十万")

具体做法可以看注释,总结下就是一个0的情况、若干个0的情况、0在结尾的情况、1在10~19的情况、1在10万+的情况。

“二”和“两”的这种读法问题可能还跟地域有关。。。

以上函数如有我没想到的情况恳请指点。