整数转化为中文数字表达

问题是一个整数(范围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万+的情况。

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

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

posted on 2017-03-31 17:25  pandawuwyj  阅读(496)  评论(0编辑  收藏  举报

导航