Trong kịch bản tôi đang viết, tôi muốn tìm chiều dài của một Fixnum trong Ruby. Tôi có thể làm <num>.to_s.length
, nhưng có cách nào để trực tiếp tìm thấy chiều dài của một Fixnum mà không cần chuyển đổi nó thành một String?Làm thế nào để xác định độ dài của một Fixnum trong Ruby?
Trả lời
puts Math.log10(1234).to_i + 1 # => 4
Bạn có thể thêm nó vào Fixnum như thế này:
class Fixnum
def num_digits
Math.log10(self).to_i + 1
end
end
puts 1234.num_digits # => 4
Mỗi lần tôi viết một cái gì đó, tôi đều ngạc nhiên. Trong MRI 1.9.3, 'n.to_s.length' nhanh hơn đối với bất kỳ số nguyên nào được biểu thị bằng một bảng Fixnum. Một _lot_ nhanh hơn: Trên hộp của tôi, 'n.to_s.length' mất một nơi nào đó giữa một phần ba và một nửa thời gian của phương pháp logarit, tùy thuộc vào độ dài của số. Nếu số đó phải được biểu diễn một Bignum, thì phương thức logarit bắt đầu thắng. Cả hai phương pháp này rất nhanh, mặc dù, khoảng 6 mili giây (đối với phương thức logarit), và giữa 0,2 và 0,3 mili giây (đối với phương thức chuỗi). –
@WayneConrad: Âm thanh như 'Math.log10' phải có triển khai khá kém hiệu quả. Tôi vừa thử một phương thức đơn giản đi qua một bảng gồm tất cả các quyền hạn của 10 mà vừa với 32/64 bit, và thực hiện một phép so sánh '> =' cho mỗi cái - đó là một liên lạc nhanh hơn 'Math.log10', nhưng vẫn chậm hơn 'to_s'. Nó có thể được thực hiện nhanh hơn bằng cách "unrolling" một tìm kiếm nhị phân của cùng một bảng, giống như unrolling một vòng lặp (sau đó bảng sẽ không cần thiết nữa - những con số tương tự sẽ được mã hóa cứng thành một loạt các điều kiện). –
Xem ra. Điều này làm tăng lỗi cho các số không dương. – sawa
Nếu bạn không muốn sử dụng regex, bạn có thể sử dụng phương pháp này:
def self.is_number(string_to_test)
is_number = false
# use to_f to handle float value and to_i for int
string_to_compare = string_to_test.to_i.to_s
string_to_compare_handle_end = string_to_test.to_i
# string has to be the same
if(string_to_compare == string_to_test)
is_number = true
end
# length for fixnum in ruby
size = Math.log10(string_to_compare_handle_end).to_i + 1
# size has to be the same
if(size != string_to_test.length)
is_number = false
end
is_number
end
Một cách khác:
def ndigits(n)
n=n.abs
(1..1.0/0).each { |i| return i if (n /= 10).zero? }
end
ndigits(1234) # => 4
ndigits(0) # => 1
ndigits(-123) # => 3
Mặc dù vòng lặp được bỏ phiếu hàng đầu là tốt đẹp, nó không phải là rất Ruby và sẽ được làm chậm cho số lượng lớn, các .to_s là một chức năng được xây dựng trong và do đó sẽ nhanh hơn nhiều. Hàm ALMOST được tích hợp sẵn sẽ nhanh hơn nhiều so với các vòng lặp hoặc vòng lặp được xây dựng.
Ruby 2.4 có phương thức Integer#digits, trả về một mảng chứa các chữ số.
num = 123456
num.digits
# => [6, 5, 4, 3, 2, 1]
num.digits.count
# => 6
EDIT:
Để xử lý số âm (nhờ @MatzFan), sử dụng giá trị tuyệt đối. Integer#abs
-123456.abs.digits
# => [6, 5, 4, 3, 2, 1]
..if nó là một số nguyên dương, nếu không 'Math :: DomainError'. Ruby còn nhiều hơn thế nữa – MatzFan
Sidenote cho của Ruby 2.4+
Tôi chạy một số tiêu chuẩn về các giải pháp khác nhau, và Math.log10(x).to_i + 1
thực sự là nhanh hơn rất nhiều so vớix.to_s.length
. comment from @Wayne Conrad đã lỗi thời. Các new solution with digits.count
là trailing xa phía sau, đặc biệt là với số lượng lớn hơn:
with_10_digits = 2_040_240_420
print Benchmark.measure { 1_000_000.times { Math.log10(with_10_digits).to_i + 1 } }
# => 0.100000 0.000000 0.100000 ( 0.109846)
print Benchmark.measure { 1_000_000.times { with_10_digits.to_s.length } }
# => 0.360000 0.000000 0.360000 ( 0.362604)
print Benchmark.measure { 1_000_000.times { with_10_digits.digits.count } }
# => 0.690000 0.020000 0.710000 ( 0.717554)
with_42_digits = 750_325_442_042_020_572_057_420_745_037_450_237_570_322
print Benchmark.measure { 1_000_000.times { Math.log10(with_42_digits).to_i + 1 } }
# => 0.140000 0.000000 0.140000 ( 0.142757)
print Benchmark.measure { 1_000_000.times { with_42_digits.to_s.length } }
# => 1.180000 0.000000 1.180000 ( 1.186603)
print Benchmark.measure { 1_000_000.times { with_42_digits.digits.count } }
# => 8.480000 0.040000 8.520000 ( 8.577174)
- 1. Làm thế nào để xác định chiều dài của một cạnh trong graphviz?
- 2. Làm cách nào để xác định độ dài của một ký tự chưa ký *?
- 3. Phân lớp Fixnum trong ruby
- 4. Làm cách nào để điền một chuỗi độ dài không xác định trong Powershell?
- 5. Làm cách nào để xác định độ dài của tệp .wav trong C#?
- 6. Làm cách nào để xác định độ dài của khung Ethernet II?
- 7. Làm thế nào để interleave mảng có độ dài khác nhau trong Ruby
- 8. Làm thế nào tôi có thể xác định lại phương pháp + (cộng) của Fixnum trong Ruby và giữ nguyên + chức năng gốc?
- 9. Làm thế nào để xác định một liên lạc dài trên Android?
- 10. Làm thế nào để tôi tìm được một hằng số được xác định trong Ruby?
- 11. Ma trận có độ dài không xác định trong MATLAB?
- 12. Làm thế nào để xác định một chức năng variadic
- 13. Làm thế nào để có được chiều dài của chuỗi dài nhất trong một mảng
- 14. Làm thế nào để tạo ra một định danh duy nhất của một chiều dài cố định trong Java?
- 15. Sử dụng size_t để xác định độ chính xác của một chuỗi trong printf C
- 16. Làm cách nào để xác định phần tương tự dài nhất của một số chuỗi?
- 17. Cách xác định độ dài của văn bản trong một UITextfield
- 18. Làm cách nào để xác định chiều dài Sequelize.STRING?
- 19. Xác định chiều dài của một String Literal
- 20. Làm thế nào để vượt qua độ dài biến chiều dài specifier trong sscanf?
- 21. Làm thế nào để xác định lại một hằng số Ruby mà không cần cảnh báo?
- 22. Django: CharField với độ dài cố định, như thế nào?
- 23. Làm cách nào để bọc lại một đoạn văn cho một độ dài dòng nhất định?
- 24. Làm thế nào tôi có thể nhận được độ dài của một mảng trong awk?
- 25. phương pháp xác định 'hợp nhất 'cho 2: Fixnum
- 26. Làm cách nào để xác định độ dài byte của chuỗi được mã hóa utf-8 bằng Python?
- 27. Làm thế nào để xác định phương pháp thể hiện trong ruby động?
- 28. Làm cách nào để xác định tốc độ CodeIgniter?
- 29. Xác định Ruby LOAD_PATH mặc định như thế nào?
- 30. Làm thế nào để xác định phương pháp [khung vuông] trong Ruby hoạt động?
"chiều dài của một' Fixnum' "là gì? Trong những gì đại diện? –
@ JörgWMittag: Có bao nhiêu chữ số trong đó. – Orcris