Module: Bsearch
- Defined in:
- lib/bsearch.rb
Overview
Ruby/Bsearch - a binary search library for Ruby.
Copyright © 2001 Satoru Takabayashi <[email protected]>
All rights reserved.
This is free software with ABSOLUTELY NO WARRANTY.
You can redistribute it and/or modify it under the terms of the Ruby’s licence.
Example:
% irb -r ./bsearch.rb
>> %w(a b c c c d e f).bsearch_first {|x| x <=> "c"}
=> 2
>> %w(a b c c c d e f).bsearch_last {|x| x <=> "c"}
=> 4
>> %w(a b c e f).bsearch_first {|x| x <=> "c"}
=> 2
>> %w(a b e f).bsearch_first {|x| x <=> "c"}
=> nil
>> %w(a b e f).bsearch_last {|x| x <=> "c"}
=> nil
>> %w(a b e f).bsearch_lower_boundary {|x| x <=> "c"}
=> 2
>> %w(a b e f).bsearch_upper_boundary {|x| x <=> "c"}
=> 2
>> %w(a b c c c d e f).bsearch_range {|x| x <=> "c"}
=> 2...5
>> %w(a b c d e f).bsearch_range {|x| x <=> "c"}
=> 2...3
>> %w(a b d e f).bsearch_range {|x| x <=> "c"}
=> 2...2
Instance Method Summary collapse
- #bfind(range = 0 ... self.length, &block) ⇒ Object
-
#bsearch_first(range = 0 ... self.length, &block) ⇒ Object
(also: #bsearch)
This method searches the FIRST occurrence which satisfies a condition given by a block in binary fashion and return the index of the first occurrence.
-
#bsearch_last(range = 0 ... self.length, &block) ⇒ Object
This method searches the LAST occurrence which satisfies a condition given by a block in binary fashion and return the index of the last occurrence.
-
#bsearch_lower_boundary(range = 0 ... self.length, &block) ⇒ Object
Return the lower boundary.
-
#bsearch_range(range = 0 ... self.length, &block) ⇒ Object
Return the search result as a Range object.
-
#bsearch_upper_boundary(range = 0 ... self.length, &block) ⇒ Object
Return the upper boundary.
Instance Method Details
#bfind(range = 0 ... self.length, &block) ⇒ Object
118 119 120 121 122 |
# File 'lib/bsearch.rb', line 118 def bfind(range = 0 ... self.length, &block) pos = self.bsearch(range, &block) return nil if pos.nil? self[pos] end |
#bsearch_first(range = 0 ... self.length, &block) ⇒ Object Also known as: bsearch
This method searches the FIRST occurrence which satisfies a condition given by a block in binary fashion and return the index of the first occurrence. Return nil if not found.
65 66 67 68 69 70 71 72 |
# File 'lib/bsearch.rb', line 65 def bsearch_first (range = 0 ... self.length, &block) boundary = bsearch_lower_boundary(range, &block) if boundary >= self.length || yield(self[boundary]) != 0 return nil else return boundary end end |
#bsearch_last(range = 0 ... self.length, &block) ⇒ Object
This method searches the LAST occurrence which satisfies a condition given by a block in binary fashion and return the index of the last occurrence. Return nil if not found.
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/bsearch.rb', line 98 def bsearch_last (range = 0 ... self.length, &block) # `- 1' for canceling `lower + 1' in bsearch_upper_boundary. boundary = bsearch_upper_boundary(range, &block) - 1 if (boundary <= -1 || yield(self[boundary]) != 0) return nil else return boundary end end |
#bsearch_lower_boundary(range = 0 ... self.length, &block) ⇒ Object
Return the lower boundary. (inside)
46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/bsearch.rb', line 46 def bsearch_lower_boundary (range = 0 ... self.length, &block) lower = range.first() -1 upper = if range.exclude_end? then range.last else range.last + 1 end while lower + 1 != upper mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational) if yield(self[mid]) < 0 lower = mid else upper = mid end end return upper end |
#bsearch_range(range = 0 ... self.length, &block) ⇒ Object
Return the search result as a Range object.
112 113 114 115 116 |
# File 'lib/bsearch.rb', line 112 def bsearch_range (range = 0 ... self.length, &block) lower = bsearch_lower_boundary(range, &block) upper = bsearch_upper_boundary(range, &block) return lower ... upper end |
#bsearch_upper_boundary(range = 0 ... self.length, &block) ⇒ Object
Return the upper boundary. (outside)
79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/bsearch.rb', line 79 def bsearch_upper_boundary (range = 0 ... self.length, &block) lower = range.first() -1 upper = if range.exclude_end? then range.last else range.last + 1 end while lower + 1 != upper mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational) if yield(self[mid]) <= 0 lower = mid else upper = mid end end return lower + 1 # outside of the matching range. end |