2011-12-29 4 views
26

Tôi đang tìm một phương thức Ruby tích hợp có chức năng giống như index nhưng sử dụng thuật toán tìm kiếm nhị phân và do đó yêu cầu một mảng được sắp xếp trước.Có tìm kiếm nhị phân tích hợp trong Ruby không?

Tôi biết mình có thể viết triển khai của riêng mình, nhưng theo "Ruby#index Method VS Binary Search", tìm kiếm lặp lại đơn giản được sử dụng bởi chỉ mục nhanh hơn phiên bản tìm kiếm nhị phân thuần túy của Ruby, vì phương pháp tích hợp được viết in C.

Ruby có cung cấp bất kỳ phương pháp tích hợp nào để tìm kiếm nhị phân không?

+0

Không cần phải viết riêng bạn: [tyler/binary_search] (https: // github .com/tyler/binary_search). Tác giả cũng đã dành thời gian để chạy một số điểm chuẩn. – sczizzo

+0

Hi sczizzo, Tôi mới dùng ruby ​​vì vậy đây là một câu hỏi khá mới, nhưng làm cách nào để thêm chức năng này vào cài đặt Ruby của tôi? Nó chỉ là một vấn đề của chạy rakefile? Cảm ơn. – Jonah

+2

Có thể dễ dàng sử dụng đá quý 'bsearch' hơn, như Marc-André đã gợi ý. Sau đó, nó khá đơn giản như 'gem install bsearch' trên dòng lệnh, và' require 'bsearch'' trong Ruby của bạn. Bạn có thể muốn [xem tài liệu hướng dẫn sử dụng] (http://rubydoc.info/gems/bsearch/1.5.0/frames). – sczizzo

Trả lời

43

Ruby 2.0 đã giới thiệu Array#bsearchRange#bsearch.

Đối với Ruby 1.9, bạn nên xem xét đá quý bsearchbinary_search. Khả năng khác là sử dụng một bộ sưu tập khác nhau hơn so với một mảng, như using rbtree

bsearch được trong backports gem của tôi, nhưng đây là một phiên bản Ruby tinh khiết, vì vậy khá chậm hơn một chút. Lưu ý rằng tìm kiếm nhị phân Ruby thuần túy sẽ vẫn nhanh hơn tìm kiếm nội tuyến tuyến tính như index hoặc include? cho mảng/dải ô đủ lớn (hoặc so sánh đắt tiền), vì nó không theo thứ tự phức tạp như O(log n)O(n).

Để chơi với nó ngay hôm nay, bạn có thể require 'backports/2.0.0/array/bsearch' hoặc require 'backports/2.0.0/range/bsearch'.

Chúc may mắn!

+0

Xin chào Marc, Cảm ơn bạn đã trả lời. Có thư viện của bên thứ 3 nào (viết bằng C) mà tôi có thể sử dụng không? – Jonah

+0

Có vẻ như có một. Đã cập nhật câu trả lời. –

+0

Và @sczizzo liên kết với một viên ngọc khác nữa. –

2

Rất nhiều đã thay đổi kể từ năm 2011, trong Ruby 2.3, bạn có thể sử dụng bsearch_index

https://ruby-doc.org/core-2.3.0/Array.html#method-i-bsearch_index

array.bsearch_index { |val| query <=> val }

+0

Có gì sai với điều này? 'arr = ['a', 'b', 'c', 'd', 'e']' 'arr.sort.bsearch {| x | 'a' == x} ' –