2012-10-26 78 views
15

thể trùng lặp:
Turning long fixed number to array RubyLàm cách nào để lặp qua các chữ số của một số nguyên?

Vâng, tôi có để lặp qua các chữ số của một số nguyên trong Ruby. Ngay bây giờ tôi chỉ chia nó thành một mảng, và sau đó lặp lại điều đó. Tuy nhiên tôi đã tự hỏi nếu có một cách nhanh hơn để làm điều này?

+0

Ý anh là gì bằng cách nhanh hơn? Hiệu quả hơn hoặc ngắn gọn hơn? –

+2

@link Btw, nó có phải là số nguyên như String hay Fixnum không? (1233 hoặc "1233") – robertodecurnex

+0

xin vui lòng cho biết làm thế nào bạn đang làm nó bây giờ vì vậy chúng tôi có một tài liệu tham khảo. – tokland

Trả lời

32

Các giải pháp ngắn nhất có lẽ là:

1234.to_s.chars.map(&:to_i) 
#=> [1, 2, 3, 4] 

Một chính thống hơn cách tiếp cận toán học:

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] 
+0

Để chỉ lặp qua các chữ số, bạn cũng có thể sử dụng các phương thức mảng mảng, phải không? n = 12.to_s tổng = (n [0..1] .to_i + n [1..2] .to_i) product = (n [0,1] .to_i * n [1, 1] .to_i) – Linju

2

Thử mod 10 (sẽ cung cấp cho bạn chữ số cuối cùng), sau đó chia cho 10 (sẽ cung cấp cho bạn phần còn lại của chữ số), lặp lại điều này cho đến khi bạn xuống đến chữ số cuối cùng. Tất nhiên, bạn sẽ phải đảo ngược thứ tự nếu bạn muốn đi qua các chữ số từ trái sang phải.

14

Bạn có thể sử dụng các thủ thuật cũ của mô đun/chia cho 10, nhưng điều này sẽ không đo được nhanh hơn trừ khi bạn có khổng lồ số, và nó sẽ cung cấp cho các chữ số bạn ngược:

i = 12345 

while i > 0 
    digit = i % 10 
    i /= 10 
    puts digit 
end 

Output:

5 
4 
3 
2 
1 
5
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] 
2

Ruby có divmod, mà sẽ tính toán cả x%10x/10 trong một đi:

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] 

Đối với những thứ như Dự án Euler, nơi tốc độ của một số tầm quan trọng, điều này là tốt đẹp để có. Xác định nó trên Integer làm cho nó có sẵn trên Bignum quá.

2

Tôi thích tính tốt nhất của ĐTV. Tôi đã viết mã này cho một dự án của tôi:

class Integer 
    def digits 
    Enumerator.new do |x| 
     to_s.chars.map{|c| x << c.to_i } 
    end 
    end 
end 

Điều này cho phép bạn truy cập vào tất cả những thứ Enumerator tốt:

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 
Các vấn đề liên quan