一种将以10为底的数字转换为以N为底的数字的算法
我正在寻找一种方法,可以将以10为底的数字转换为N可以很大的以N为底的数字。具体来说,我正在考虑转换为以85为基数并再次返回。有人知道执行转换的简单算法吗?理想情况下,它将提供以下内容:
to_radix(83992, 85) -> [11, 53, 12]
任何想法表示赞赏!
罗雅
回答:
这是一个很有趣的问题,所以我有些过分了:
class Integer def to_base(base=10)
return [0] if zero?
raise ArgumentError, 'base must be greater than zero' unless base > 0
num = abs
return [1] * num if base == 1
[].tap do |digits|
while num > 0
digits.unshift num % base
num /= base
end
end
end
end
这适用于任意基础。它仅适用于整数,尽管没有理由不能将其扩展为可使用任意数字。此外,它忽略数字的符号。再次,没有理由为什么 必须
这样做,但是主要是我不想提出在返回值中返回符号的约定。
class Integer old_to_s = instance_method(:to_s)
define_method :to_s do |base=10, mapping=nil, sep=''|
return old_to_s.bind(self).(base) unless mapping || base > 36
mapping ||= '0123456789abcdefghijklmnopqrstuvwxyz'
return to_base(base).map {|digit| mapping[digit].to_s }.join(sep)
end
end
[Fixnum, Bignum].each do |klass|
old_to_s = klass.instance_method(:to_s)
klass.send :define_method, :to_s do |base=10, mapping=nil, sep=''|
return old_to_s.bind(self).(base) unless mapping || base > 36
return super(base, mapping, sep) if mapping
return super(base)
end
end
我还扩展了该to_s
方法,使其可以使用大于36的底数。如果要使用大于36的底数,则必须传入一个将“数字”映射为字符串的映射对象。(实际上,所需要做的就是提供一个对象,该对象可以响应[]
并返回响应的对象to_s
。因此,字符串是完美的,但是例如整数数组也可以使用。)
它还接受一个可选的分隔符,该分隔符用于分隔数字。
例如,这允许您将IPv4地址设置为以256为基数的数字,并使用映射的标识和'.'
分隔符来设置其格式:
2_078_934_278.to_s(256, Array.new(256) {|i| i }, '.') # => '123.234.5.6'
这是一个(不完整的)测试套件:
require 'test/unit'class TestBaseConversion < Test::Unit::TestCase
def test_that_83992_in_base_85_is_11_53_12
assert_equal [11, 53, 12], 83992.to_base(85)
end
def test_that_83992_in_base_37_is_1_24_13_2
assert_equal [1, 24, 13, 2], 83992.to_base(37)
end
def test_that_84026_in_base_37_is_1_24_13_36
assert_equal [1, 24, 13, 36], 84026.to_base(37)
end
def test_that_0_in_any_base_is_0
100.times do |base|
assert_equal [0], 0.to_base(base)
assert_equal [0], 0.to_base(1 << base)
assert_equal [0], 0.to_base(base << base)
end
end
def test_that_84026_in_base_37_prints_1od_
assert_equal '1od_', 84026.to_s(37, '0123456789abcdefghijklmnopqrstuvwxyz_')
end
def test_that_ip_address_formatting_works
addr = 2_078_934_278
assert_equal '123.234.5.6', addr.to_s(256, (0..255).to_a, '.')
assert_equal '123.234.5.6', addr.to_s(256, Array.new(256) {|i| i}, '.')
end
def test_that_old_to_s_still_works
assert_equal '84026', 84026.to_s
assert_equal '1su2', 84026.to_s(36)
end
end
以上是 一种将以10为底的数字转换为以N为底的数字的算法 的全部内容, 来源链接: utcz.com/qa/400189.html