将整数改为没有宝石的红宝石

时间:2015-05-09 20:24:32

标签: ruby

我正在尝试将数字从整数更改为100,但遇到了一些麻烦,任何人都可以指出我的代码缺少的内容:

def in_words(integer)

    numWords = { 
    0=>"zero",
    1=>"one",
    2=>"two",
    3=>"three",
    4=>"four",
    5=>"five",
    6=>"six",
    7=>"seven",
    8=>"eight",
    9=>"nine",
    10=>"ten",
    11=>"eleven",
    12=>"twelve",
    13=>"thirteen",
    14=>"fourteen",
    15=>"fifteen",
    16=>"sixteen",
    17=>"seventeen",
    18=>"eighteen",
    19=>"nineteen",
    20=>"twenty",
    30=>"thirty",
    40=>"fourty",
    50=>"fifty",
    60=>"sixty",
    70=>"seventy",
    80=>"eighty",
    90=>"ninety",
    100=>"one hundred"
    }

    array = integer.to_s.split('')
    new_array = []

    numWords.each do |k,v|
        array.each do |x|
            if x = k
                new_array.push(v)
            end 
        end 
    end 

    new_array.join('')

end

现在我做的时候:

inwords(0)

我得到以下内容:         =>" zeroonetwothreefourfivesixseveneightnineteneleventwelvethirteenfourteenfiftee nsixteenseventeeneighteennineteentwentythirtyfourtyfiftysixtyseventyeightyninetyone hundred"

4 个答案:

答案 0 :(得分:2)

修改

我注意到您的代码多次遍历数组并在=语句中使用==而不是if

使用哈希#[]方法结合#map方法,您的代码可以更有效率,这里是一个单线替代方案:

 integer.to_s.split('').map {|i| numWords[i.to_i]} .join ' '

另外,请注意integer.to_s.split('')会将数组拆分成一位数的字符串,因此数字最多为100与我提出的代码无关。

要使用哈希中的所有数字,您可能需要使用正则表达式来标识您拥有的数字。一种方法是执行以下操作(我将其写在一行中,但是使用每个步骤的变量名称很容易将其分解):

integer.to_s.gsub(/(\d0)|([1]?\d)/) {|v| v + " "} .split.map {|i| numWords[i.to_i]} .join ' '
# or:
integer.to_s.gsub(/(#{numWords.keys.reverse.join('|')})/) {|v| v + " "} .split.map {|i| numWords[i.to_i]} .join ' '
# out = integer.to_s
# out = out.gsub(/(#{numWords.keys.reverse.join('|')})/) {|v| v + " "}
# out = out.split
# out = out.map {|i| numWords[i.to_i]}
# out = out.join ' '

修改2

由于您现在提到您希望该方法接受最多100个数字并返回实际数字(23 =>二十三),因此可能采取不同的方法...我建议您更新问题也是如此。

def in_words(integer)

    numWords = { 
    0=>"zero",
    1=>"one",
    2=>"two",
    3=>"three",
    4=>"four",
    5=>"five",
    6=>"six",
    7=>"seven",
    8=>"eight",
    9=>"nine",
    10=>"ten",
    11=>"eleven",
    12=>"twelve",
    13=>"thirteen",
    14=>"fourteen",
    15=>"fifteen",
    16=>"sixteen",
    17=>"seventeen",
    18=>"eighteen",
    19=>"nineteen",
    20=>"twenty",
    30=>"thirty",
    40=>"fourty",
    50=>"fifty",
    60=>"sixty",
    70=>"seventy",
    80=>"eighty",
    90=>"ninety",
    100=>"one hundred"
    }

    raise "cannot accept such large numbers" if integer > 100
    raise "cannot accept such small numbers" if integer < 0

    return "one hundred" if integer == 100

    if integer < 20 || integer %10 == 0
       numWords[integer]
    else 
       [numWords[integer / 10 * 10], numWords[integer % 10]].join ' '
    end
end

integer / 10 * 10使得数字成为一个整数(十,二十,等等),因为整数没有分数(所以,23/10 == 2和2 * 10 == 20 )。使用integer.round(-1)可以实现同样的目标,这可能更好。

答案 1 :(得分:0)

看起来你要做的就是从隐式哈希

中找到一个映射
module NumWords
 INT2STR = { 
    0=>"zero",
    1=>"one",
    2=>"two",
    3=>"three",
    4=>"four",
    5=>"five",
    6=>"six",
    7=>"seven",
    8=>"eight",
    9=>"nine",
    10=>"ten",
    11=>"eleven",
    12=>"twelve",
    13=>"thirteen",
    14=>"fourteen",
    15=>"fifteen",
    16=>"sixteen",
    17=>"seventeen",
    18=>"eighteen",
    19=>"nineteen",
    20=>"twenty",
    30=>"thirty",
    40=>"fourty",
    50=>"fifty",
    60=>"sixty",
    70=>"seventy",
    80=>"eighty",
    90=>"ninety",
    100=>"one hundred"
    }
    module_function
    def in_words(integer)
      INT2STR[integer]
    end
end

上面的代码将哈希定义与方法调用分开,这样每次调用in_words时都不会重新创建哈希值。

您还可以使用Hash#fetch代替Hash#[],正如安德烈指出的那样。

答案 2 :(得分:0)

您的测试x = k是否是您的第一个问题(以两种方式)。

首先,if x = k表示将k的值分配给x然后执行if块,如果该值为true(基本上除{{1}之外的任何值}或false)。

实际应该测试的是nil,如果x == k等于x,则会返回true。

第二个问题是您将数字转换为字符串表示数组,因此您要进行比较,例如k。这不会返回true,因为它们是不同的类型。

如果您将其转换为if "0" == 0,那么您的if块将被执行并且您将获得:

if x.to_i == k

然后你可以转到下一个问题,即你正在逐位查看你的数字,你正在测试的一些值需要识别两位数字:

> in_words(0)
=> "zero"

你可能正在考虑一个不同的问题 - 或许这就是你想要一直回答的问题!

答案 3 :(得分:0)

这是你可能采取的另一种方式:

ONES_TO_TEXT  = { 0=>"zero", 1=>"one", 2=>"two",   3=>"three", 4=>"four",
                  5=>"five", 6=>"six", 7=>"seven", 8=>"eight", 9=>"nine" }

TEENS_TO_TEXT = { 10=>"ten", 11=>"eleven", 12=>"twelve",
                  13=>"thirteen", 15=>"fifteen" }

TENS_TO_TEXT  = { 2=>"twenty", 3=>"thirty", 5=>"fifty", 8=>"eighty" }

def in_words(n)
  raise ArgumentError, "#{n} is out-of_range" unless (0..100).cover?(n)
  case n.to_s.size
  when 1 then ONES_TO_TEXT[n]
  when 3 then "one hundred"
  else
    case n
    when (10..19)
      TEENS_TO_TEXT.key?(n) ? TEENS_TO_TEXT[n] : ONES_TO_TEXT[n]+"teen"
    else
      t,o = n.divmod(10)
      (TENS_TO_TEXT.key?(t) ? TENS_TO_TEXT[t]  : ONES_TO_TEXT[t]+"ty") +
        (o.zero? ? '' : "-#{ONES_TO_TEXT[o]}")
    end
  end
end

我们试一试:

in_words(5)   #=> "five" 
in_words(10)  #=> "ten" 
in_words(15)  #=> "fifteen" 
in_words(20)  #=> "twenty" 
in_words(22)  #=> "twenty-two" 
in_words(30)  #=> "thirty" 
in_words(40)  #=> "fourty" 
in_words(45)  #=> "fourty-five" 
in_words(50)  #=> "fifty" 
in_words(80)  #=> "eighty" 
in_words(99)  #=> "ninety-nine" 
in_words(100) #=> "one hundred" 

此处增加的复杂性可能不合理,但是当n的最大允许值远大于100时,这种方法实际上可以简化计算。