Как выполнить итерацию по цифрам целого числа?
Возможный дубликат:
Превращение длинного фиксированного числа в массив Ruby
Ну, я должен перебирать цифры целого числа в Ruby. Прямо сейчас я просто разбил его на массив, а затем повторил это. Однако мне было интересно, есть ли более быстрый способ сделать это?
Ответы
Ответ 1
Самое короткое решение, вероятно, следующее:
1234.to_s.chars.map(&:to_i)
#=> [1, 2, 3, 4]
Более ортодоксальный математический подход:
class Integer
def digits(base: 10)
quotient, remainder = divmod(base)
quotient == 0 ? [remainder] : [*quotient.digits(base: base), remainder]
end
end
0.digits #=> [0]
1234.digits #=> [1, 2, 3, 4]
0x3f.digits(base: 16) #=> [3, 15]
Ответ 2
Вы можете использовать старый трюк модуля/деления на 10, но это не будет заметно быстрее, если у вас нет огромных чисел, и он будет давать цифры вам назад:
i = 12345
while i > 0
digit = i % 10
i /= 10
puts digit
end
Вывод:
5
4
3
2
1
Ответ 3
split=->(x, y=[]) {x < 10 ? y.unshift(x) : split.(x/10, y.unshift(x%10))}
split.(1000) #=> [1,0,0,0]
split.(1234) #=> [1,2,3,4]
Ответ 4
Попробуйте по mod на 10 (даст вам последнюю цифру), затем разделите на 10 (вы получите остальную часть цифр), повторите это, пока не опуститесь до последней цифры. Конечно, вам придется отменить порядок, если вы хотите пройти цифры слева направо.
Ответ 5
Ruby имеет divmod
, который будет вычислять как x%10
, так и x/10
за один раз:
class Integer
def split_digits
return [0] if zero?
res = []
quotient = self.abs #take care of negative integers
until quotient.zero? do
quotient, modulus = quotient.divmod(10) #one go!
res.unshift(modulus) #put the new value on the first place, shifting all other values
end
res # done
end
end
p 135.split_digits #=>[1, 3, 5]
Для таких вещей, как Project Euler, где скорость имеет некоторое значение, это приятно иметь. Определение его на Integer заставляет его быть доступным и на Bignum.
Ответ 6
Мне нравится доброжелательность. Я написал этот код для моего проекта:
class Integer
def digits
Enumerator.new do |x|
to_s.chars.map{|c| x << c.to_i }
end
end
end
Это дает вам доступ ко всем хорошим материалам Enumerator:
num = 1234567890
# use each to iterate over the digits
num.digits.each do |digit|
p digit
end
# make them into an array
p num.digits.to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
# or take only some digits
p num.digits.take(5) # => [1, 2, 3, 4, 5]
# you can also use next and rewind
digits = num.digits
p digits.next # => 1
p digits.next # => 2
p digits.next # => 3
digits.rewind
p digits.next # => 1