我如何描述Ruby中的所有整数

时间:2014-09-04 22:53:36

标签: ruby

我正在尝试编写一个基本程序,当用户输入数字时,该程序会吐出数字的英文版本:

input = 44
output = fourty four

有没有办法描述所有整数?

基本上我希望执行看起来像:

number = gets.chomp

if number != (whatever the nomenclature is for integer)

puts 'Please enter a positive number'

或者那种效果。

2 个答案:

答案 0 :(得分:5)

你可以使用numbers_and_words gem:

来做到这一点

https://github.com/kslazarev/numbers_and_words

它也支持英语以外的语言。

例如:

21.to_words
=> "twenty-one"

44.to_words
=> "forty-four"

答案 1 :(得分:1)

我修改了Fixnum类并添加了一个方法in_words。我做的是我将每个数字分成三组,所以100000转为[100,000]和123456789转变为[123,456,789]或1543转变为[1,453]然后我逐个元素和命名元素中的每个数字并添加适当的单词,如数百和数千。如果您有任何问题,我很乐意解释!

class Fixnum
  LOW = %w(zero one two three four five six seven
    eight nine ten eleven twelve thirteen fourteen
    fifteen sixteen seventeen eighteen nineteen)
  TWO_DIGIT = %w(ten twenty thirty forty fifty sixty seventy eighty ninety)
  BIG_NUMS = %w(hundred thousand million billion trillion)

  def in_words
    # Break up number into bytes with three bits each
    # Then turn each byte into words

    # Break into bytes
    number = self.to_s.reverse
    bytes = []
    num_bytes = (number.length.to_f / 3.0).ceil()
    num_bytes.times { |x| bytes << number[(x*3)..(x*3)+2].reverse }

    #puts bytes.reverse.join(",")

    # Turn bytes into words bit by bit
    word = []
    text = ""
    bytes.each_with_index do |byte, i|
      text = ""

      # First bit
      text = LOW[byte[0].to_i] if (byte.length == 3 && byte[0].to_i != 0) || byte.length == 1

      # Add hundred if 3 bits
      text += " hundred" if byte.length == 3 && byte[0].to_i != 0

      # Second bit
      if byte.length == 3 # Three bits
        if byte[1].to_i > 1 # Second bit greater than teens
          text += " " + TWO_DIGIT[byte[1].to_i + (-1)]
        elsif byte[1].to_i != 0 # Second bit not zero
          text += " " + LOW[byte[1..2].to_i]
        end
      elsif byte.length == 2 # Two bits
        if byte[0].to_i > 1 # Greater than teens
          text += " " + TWO_DIGIT[byte[0].to_i + (-1)]
          text += " " + LOW[byte[1].to_i] if byte[1].to_i != 0
        else # Less than twenty
          text += LOW[byte[0..1].to_i]
        end
      end

      # Third bit if three bytes and second bit > teens and third bit nonzero
      text += " " + LOW[byte[2].to_i] if byte[1].to_i != 1 && byte[2].to_i > 0 && byte.length > 2

      # Add trillion/billion/million/thousand
      text += " " + BIG_NUMS[i] if i != 0 && byte.to_i != 0

      word << text.strip if text.strip != ""

    end
    word.reverse.join(" ")
  end
end

因为我修改了Fixnum对象,你可以从任何Fixnum调用它,例如44.in_words

编辑:看起来您可能正在尝试检查整数的输入。我建议制作一个函数来处理:

def check_input(i)
  if !(i =~ /^[0-9]+$/)
    puts "Sorry, that is an invalid input! Please try again"
    i = check_input(gets.chomp)
  end
  i.to_i
end

我认为处理这种情况的最佳方法是使用正则表达式(模式匹配)。基本上你的函数检查输入是否不是数字,然后它再次要求输入。如果是数字,则函数返回数字。 /^[0-9]+$/是正则表达式。 ^表示该行的开头,$表示该行的结尾。 [0-9]匹配任何数字0到9(正如Tin Man评论的那样,您也可以使用\d来表示任何数字并且它是等效的),+表示匹配前一个数字(任何数字)数字)至少一次。