-
-
Save gonglexin/365682 to your computer and use it in GitHub Desktop.
Ruby:convert RMB currency to chinese describe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$KCODE = 'u' | |
# Goal: 小写金额转换为大写金额 | |
# Limit: 金额整数位支持到亿位,小数点后支持两位并且不支持四舍五入 | |
class ChineseFee | |
attr_reader :chn_numbers, :chn_units, :chn_decimals | |
def initialize | |
@chn_numbers = %w(零 壹 贰 叁 肆 伍 陆 柒 捌 玖) | |
@chn_units = %w(元 拾 佰 仟 万 拾万 佰万 仟万 亿) | |
@chn_decimals = %w(角 分) | |
end | |
def convert | |
read = gets | |
if is_a_number?(read) | |
orig_numbers = read | |
else | |
#超出金额表示范围,目前仅支持亿位,最大数字9位及两位小数 | |
return false | |
end | |
integers = orig_numbers.split('.').first.split('') | |
decimals = orig_numbers.include?('.') ? orig_numbers.split('.').last.split('') : nil | |
result = [] | |
#“零”字符标记 | |
first_zero = true | |
#整数表示处理 | |
integers.each_index { |i| | |
#一般0条件处理 | |
if integers[i].eql? "0" and first_zero == true | |
first_zero = false | |
#特别处理整数部分个位为0时的情况处理 | |
if i == (integers.length - 1) | |
result << @chn_units[ integers.length - i - 1 ] | |
else | |
result << @chn_numbers[ integers[i].to_i ] | |
end | |
elsif integers[i].eql? "0" and first_zero == false | |
#在连续非第一个0时,不作处理,直接跳出 | |
#但还是有特列,如10000之类,需要处理个位 | |
#特别处理整数部分遇0但单位需要加上 | |
if i == (integers.length - 1) | |
result.delete_at(-1) #遇到类如1000之类,需要处理最后一个0,即去掉这个特例中的0 | |
result << @chn_units[ integers.length - i - 1 ] | |
end | |
else | |
#遇到非零值后,重置遇零标记 | |
first_zero = true | |
result << @chn_numbers[ integers[i].to_i ] | |
result << @chn_units[ integers.length - i - 1 ] | |
end | |
} | |
#尾数条件 | |
#“零”角处理 | |
first_zero = true | |
unless decimals.nil? | |
decimals.each_index { |i| | |
if decimals[i].eql? "0" and first_zero == true | |
result << @chn_numbers[ decimals[i].to_i ] | |
else | |
result << @chn_numbers[ decimals[i].to_i] | |
result << @chn_decimals[i] | |
end | |
} | |
else | |
result << "整" | |
end | |
#返回中文金额 | |
return result.flatten.to_s | |
end | |
private | |
#regex只支持前面整数支持9位,小数点后只处理两位 | |
def is_a_number?(s) | |
s.to_s.match(/\A\d{1,9}(\.\d{1,2}){0,3}\z/) == nil ? false : true | |
end | |
end | |
# 测试代码 | |
if __FILE__ == $PROGRAM_NAME | |
require File.dirname(__FILE__) + '/testhelpers' | |
class TestChineseFee < Test::Unit::TestCase | |
def setup | |
@chn_fee = ChineseFee.new | |
end | |
#输入特例数据返回 | |
must "return correct chn string about zero case" do | |
$stdin = StringIO.new "1000.45" | |
assert_equal "壹仟元肆角伍分", @chn_fee.convert,"返回结果不正确" | |
$stdin = StringIO.new "110005000.05" | |
assert_equal "壹亿壹仟万零伍仟元零伍分",@chn_fee.convert,"返回结果不正确" | |
end | |
must 'return chinese currences' do | |
$stdin = StringIO.new "1234.45" | |
assert_equal "壹仟贰佰叁拾肆元肆角伍分", @chn_fee.convert,"返回结果不正确" | |
end | |
must 'read invald input number,return false' do | |
$stdin = StringIO.new "invalid info" | |
assert !@chn_fee.convert,'not read input number' | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment