首页 > 解决方案 > 罗马到整数重构

问题描述

我正在编写一个方法roman_to_integer(roman_string),它将罗马数字转换为整数:'IV' 到 4,'XVI' 到 16,等等。

 ROMAN_TO_INT = {
      "I" => 1,
      "IV" => 4,
      "V" => 5,
      "IX" => 9,
      "X" => 10,
      "XL" => 40,
      "L" => 50,
      "XC" => 90,
      "C" => 100,
      "CD" => 400,
      "D" => 500,
      "CM" => 900,
      "M" => 1000
    }

    def roman_to_integer(roman_string)
      # TODO: translate roman string to integer
      number = 0
      str = roman_string.dup
      until str.size.zero?
        last_two_characters = str.slice(-2, 2)
        if ROMAN_TO_INT.key?(last_two_characters)
          number += ROMAN_TO_INT[last_two_characters]
          str.chop!
        else
          number += ROMAN_TO_INT[str.slice(-1)]
        end
        str.chop!
      end
      number
    end

我怎样才能使我的方法更短?Rubocop 只允许 10 行。我正在尝试,但总是以至少 13 个结尾。

标签: rubyrefactoring

解决方案


不是真正的重构,而是减少行数的选项:

ROMAN_TO_INT =
  {
    i: 1,
    v: 5,
    x: 10,
    l: 50,
    c: 100,
    d: 500,
    m: 1000
  }


def roman_to_int roman
  value_map = roman.split('').map { |e| ROMAN_TO_INT[e.downcase.to_sym] }
  value_map.map.with_index do |e, idx| 
    unless value_map[idx + 1].nil?
    then
      value_map[idx + 1] > e ? -e : e
    else e
    end
  end.sum
end

roman = "MDCCLXXVI"
roman_to_int roman #=> 1776

如果罗马符号无效,它不会发出警报,例如:

roman = "VMII" # incorrect notation for 997
roman_to_int roman #=> 997

roman = "CMXCVII" # correct notation for 997
roman_to_int roman #=> 997

推荐阅读