Ruby中+和

Ruby中+和,ruby,Ruby,下面是两个相同的类,当行罗马数字[character.to_i*10**index]这一行是一个问题时,运算符+和之间存在差异 ROMAN_NUMERALS[character.to_i * 10 ** index] << roman_numeral 它将返回一个字符串,它是正确的罗马数字键加上罗马数字的值,这是您想要的,但它也改变了罗马数字哈希中的值!电铲操作员既然您的问题已经得到了回答,我想建议一种替代方法以及一种不同的方法来执行您的测试。这需要RubyV1.9+,因此我们可以

下面是两个相同的类,当行罗马数字[character.to_i*10**index]这一行是一个问题时,运算符+和之间存在差异

ROMAN_NUMERALS[character.to_i * 10 ** index] << roman_numeral

它将返回一个字符串,它是正确的罗马数字键加上罗马数字的值,这是您想要的,但它也改变了罗马数字哈希中的值!电铲操作员既然您的问题已经得到了回答,我想建议一种替代方法以及一种不同的方法来执行您的测试。这需要RubyV1.9+,因此我们可以根据散列键的顺序来确定

代码

首先,颠倒散列元素的顺序

RNR = Hash[ROMAN_NUMERALS.to_a.reverse]
  #=> {3000=>"MMM", 2000=>"MM", 1000=>"M",..., 2=>"II", 1=>"I", 0=>""}  
然后:

例子

现在,让我们为各种整数值调用Integerto_roman和Stringroman_to_integer:

def check_one(i)
  roman = i.to_roman
  puts "#{i}.to_roman = #{roman}, #{roman}.roman_to_integer = " +
    #{roman.roman_to_integer}"
end

check_one(402)  # 'CDII'
  # 402.to_roman = CDII, CDII.roman_to_integer = 402
check_one(575)  # 'DLXXV'
  # 575.to_roman = DLXXV, DLXXV.roman_to_integer = 575
check_one(911)  # 'CMXI'
  # 911.to_roman = CMXI, CMXI.roman_to_integer = 911
check_one(1024) # 'MXXIV'
  # 1024.to_roman = MXXIV, MXXIV.roman_to_integer = 1024
check_one(3000) # 'MMM'
  # 3000.to_roman = MMM, MMM.roman_to_integer = 3000
测验

因此,现在在您的测试中,您可以使用:

def test_all(n)
  (1..n).each { |i| test_one(i) }
end

def test_one(i)
  roman = i.to_roman
  assert_equal(i, roman.roman_to_integer, "#{i}.to_roman=#{roman}, " +
    "#{roman}.roman_to_integer = #{roman.roman_to_integer}")
end

现在,你写了一个完全不同的问题。旁注:这可能应该用一个map来写。然后在末尾使用_index+join。你看过文档了吗?这里清楚地解释了不同之处。嗨,我的帖子编辑得不错,但我重新考虑了结果,不得不修改下半场,所以你的编辑有点被风吹了……没关系,@SteveTurczyn谢谢但是我想这会稍微慢一点?因为它是从被转换的数字到数字的数字的循环。不过这是一个有趣的方法。我建议你进行基准测试,并以答案的形式进行报告。如果你以前没用过,这很容易。看,例如,我的答案。看起来你的答案更快。
RNR = Hash[ROMAN_NUMERALS.to_a.reverse]
  #=> {3000=>"MMM", 2000=>"MM", 1000=>"M",..., 2=>"II", 1=>"I", 0=>""}  
class Integer
  def to_roman
    num = self
    roman = ""
    while num > 0
      i,r = RNR.find { |i,r| i <= num }
      roman << r
      num -= i
    end
    roman
  end
end
RNRI = RNR.invert
  #=> {"MMM"=>3000, "MM"=>2000, "M"=>1000,..., "II"=>2, "I"=>1, ""=>0} 

class String
  def roman_to_integer
    num = 0
    roman = self
    while roman.size > 0
      r, i = RNRI.find { |r,m| roman =~ /^#{r}/ }
      num += i
      roman = roman[r.size..-1]
    end
    num
  end  
end
def check_one(i)
  roman = i.to_roman
  puts "#{i}.to_roman = #{roman}, #{roman}.roman_to_integer = " +
    #{roman.roman_to_integer}"
end

check_one(402)  # 'CDII'
  # 402.to_roman = CDII, CDII.roman_to_integer = 402
check_one(575)  # 'DLXXV'
  # 575.to_roman = DLXXV, DLXXV.roman_to_integer = 575
check_one(911)  # 'CMXI'
  # 911.to_roman = CMXI, CMXI.roman_to_integer = 911
check_one(1024) # 'MXXIV'
  # 1024.to_roman = MXXIV, MXXIV.roman_to_integer = 1024
check_one(3000) # 'MMM'
  # 3000.to_roman = MMM, MMM.roman_to_integer = 3000
def test_all(n)
  (1..n).each { |i| test_one(i) }
end

def test_one(i)
  roman = i.to_roman
  assert_equal(i, roman.roman_to_integer, "#{i}.to_roman=#{roman}, " +
    "#{roman}.roman_to_integer = #{roman.roman_to_integer}")
end