`
realfun
  • 浏览: 25318 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

用Ruby做中文数字和阿拉伯数字之间的互相转换,附简单测试代码

阅读更多
Ruby代码 : 用Ruby做中文数字和阿拉伯数字之间的互相转换
001 #中文数字和阿拉伯数字之间的互相转换
002 #  比如: 138 <=> 一百三十八
003 #
004 #作者: 半瓶墨水 http://www.2maomao.com/blog/
005 $KCODE = 'u'
006 require 'jcode'
007 require 'iconv'
008
009 $cn_nums = %w{零 一 二 三 四 五 六 七 八 九}
010 $cn_decs =   %w{十 百 千 万 十 百 千 亿}
011 $conv = Iconv . new ( 'gbk' , 'utf-8' )
012
013 $cn_nums_map = {
014     '〇' => 0 ,
015     '一' => 1 ,
016     '二' => 2 ,
017     '三' => 3 ,
018     '四' => 4 ,
019     '五' => 5 ,
020     '六' => 6 ,
021     '七' => 7 ,
022     '八' => 8 ,
023     '九' => 9 ,
024
025     '零' => 0 ,
026     '壹' => 1 ,
027     '贰' => 2 ,
028     '叁' => 3 ,
029     '肆' => 4 ,
030     '伍' => 5 ,
031     '陆' => 6 ,
032     '柒' => 7 ,
033     '捌' => 8 ,
034     '玖' => 9 ,
035
036     '貮' => 2 ,
037     '两' => 2 ,
038 }
039
040 $cn_decs_map = {
041     '个' => 1 ,
042     '十' => 10 ,
043     '拾' => 10 ,
044     '百' => 100 ,
045     '佰' => 100 ,
046     '千' => 1000 ,
047     '仟' => 1000 ,
048     '万' => 10000 ,
049     '萬' => 10000 ,
050     '亿' => 100000000 ,
051     '億' => 100000000 ,
052     '兆' => 1000000000000 ,
053 }
054
055 def uputs ( str )
056     puts $conv . iconv ( str )
057 end
058
059 class NumCnConv
060 private
061     def digit2cn ( d )
062         $cn_nums [ d - '0' [ 0 ]]
063     end
064     def is_all_zero ( str )
065         return str == ( '0' * str . size )
066     end
067
068 public
069     def num2cn ( num )
070         str = num . to_s
071 #        print str + ":"
072         result = []
073         str = str . reverse
074         zero_count = 0       #zero_count after last non-zero digit
075         index = 0            #the index for the numbers
076         first_zero = true    #don't need to insert 零 for numbers like /[1-9]+0+/
077         str_wan_yi = nil     #insert 万 & 亿 when needed
078         while index < str . size do #3 0423 4829
079             d = str [ index ]
080             #puts "index = #{index} (#{d.chr})"
081             if ( d - '0' [ 0 ] > 0 )
082                 if zero_count > 0
083                     zero_count = 0
084                     result << digit2cn ( '0' [ 0 ] ) if ! first_zero
085                     if str_wan_yi != nil
086                         result << str_wan_yi
087                         str_wan_yi = nil
088                     end
089                 end
090                 result << $cn_decs [ ( index - 1 ) % ( $cn_decs . size ) ] if index > 0
091                 result << digit2cn ( d )
092                 first_zero = false
093             else
094                 if ( index > 0 && ( index % 4 ) == 0 && ! is_all_zero ( str [ index , 4 ] ) )
095                     str_wan_yi = $cn_decs [ ( index - 1 ) % ( $cn_decs . size ) ]
096                 end
097                 zero_count += 1
098             end
099             index += 1
100         end
101         if zero_count > 0
102             zero_count = 0
103             result << digit2cn ( '0' [ 0 ] )
104         end
105         result = result . reverse
106
107         res = result . join
108         if res =~ /^一十/
109             res = res [ '一' . size , res . size - '一' . size ]
110         end
111 #        uputs res
112         return res
113     end
114
115     def cn2num ( str )
116         #remove 零
117         num_str = ''
118         last = nil
119         str . scan ( /./u ) do | c |
120             if ( ! $cn_nums_map [ c ] && ! $cn_decs_map [ c ] )
121                 uputs " #{ str }   是个错误的数字串"
122                 return nil
123             end
124             num_str += c if c != '零'
125             last = c
126         end
127         if num_str =~ /^十/
128             num_str = '一' + num_str
129         end
130
131         sums = []
132         temp_sum = 0
133         last_num = 0
134         num_str . scan ( /./u ) do | ch |
135             if num = $cn_nums_map [ ch ]
136                 last_num = num
137             else
138                 dec = $cn_decs_map [ ch ]
139                 if dec < 10000
140                     temp_sum += last_num * dec
141                 else
142                     #find back for the one that exceeds current dec
143                     sums . each_with_index do | x , i |
144                         if x < dec * 10 #10 is here for situation like 两亿亿
145                             sums [ i ] = x * dec
146                         else
147                             break
148                         end
149                     end
150                     temp_sum += last_num
151                     sums << temp_sum * dec
152                     temp_sum = 0
153                 end
154                 last_num = 0
155             end
156         end
157         sums << temp_sum + last_num
158
159         sum = 0
160         sums . each do | x |
161             sum += x
162         end
163         return sum
164     end
165 end
166
167 #$cn_nums_map.each do |key, value|
168     #uputs key + "=>" + value.to_s
169 #end
170
171 #myconv = NumCnConv.new
172 #puts myconv.cn2num('两亿亿')
173
174 #-------------------------------------------
175 #测试程序
176 require 'test\unit'
177
178 $td_map = {
179     #1 digit 个
180     '零' => 0 ,
181     '一' => 1 ,
182     '二' => 2 ,
183     '三' => 3 ,
184     '四' => 4 ,
185     '五' => 5 ,
186     '六' => 6 ,
187     '七' => 7 ,
188     '八' => 8 ,
189     '九' => 9 ,
190
191     #2 digits 十
192     '十' => 10 ,
193     '十一' => 11 ,
194     '二十' => 20 ,
195     '二十一' => 21 ,
196
197     #3 digits 百
198     '一百' => 100 ,
199     '一百零一' => 101 ,
200     '一百一十' => 110 ,
201     '一百二十三' => 123 ,
202
203     #4 digits 千
204     '一千' => 1000 ,
205     '一千零一' => 1001 ,
206     '一千零一十' => 1010 ,
207     '一千一百' => 1100 ,
208     '一千零二十三' => 1023 ,
209     '一千二百零三' => 1203 ,
210     '一千二百三十' => 1230 ,
211
212     #5 digits 万
213     #@@@@
214     '一万' => 10000 ,
215     '一万零一' => 10001 ,
216     '一万零一十' => 10010 ,
217     '一万零一百' => 10100 ,
218     '一万一千' => 11000 ,
219     '一万零一十一' => 10011 ,
220     '一万零一百零一' => 10101 ,
221     '一万一千零一' => 11001 ,
222     '一万零一百一十' => 10110 ,
223     '一万一千零一十' => 11010 ,
224     '一万一千一百' => 11100 ,
225     '一万一千一百一十'
2
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics