Re: find function

new topic     » goto parent     » topic index » view thread      » older message » newer message

Mike,

Don't have the time to benchmark, but here's the binary search routine I
always use. I believe I got the basic idea from a QuickBasic textbook,
although the Euphoria implementation is my own. Enjoy!

Gabriel


global function find_sorted(object x, sequence s)
-- does a binary search on a sorted sequence
-- returns index location if found, 0 if not
-- assumes that sequence s has been sorted prior to this call
integer lo, hi, mid, c
   lo = 1
   hi = length(s)

   while lo <= hi do
      mid = floor((lo + hi) / 2)
      c = compare(x, s[mid])
      if    c < 0 then  -- x < s[mid]
         hi = mid - 1
      elsif c > 0 then  -- x > s[mid]
         lo = mid + 1
      else              -- x = s[mid]
         return mid
      end if
   end while

   return 0
end function


-----Original Message-----
From: Mike [mailto:vulcan at WIN.CO.NZ]
Sent: Monday, October 18, 1999 2:29 PM
To: EUPHORIA at LISTSERV.MUOHIO.EDU
Subject: find function


Below is a function that can be used in place of Euphoria's find() IF the
list to be searched is sorted ( in ascending order).
I have written it to manage a word list for my windows editor ( which is
progressing slowly sad  ) but I thought that some may find it useful and
maybe someone could optimize it especially for a small list where find()
currently has the advantage. For any list the search time for almost all
elements is fairly constant regardless of where they are located. In the
case of a massive list where the element to be located is NOT near the start
of the list then this function really shows it's colours. I did have a look
at hash.ex and tree.ex in euphoria\demo but these do not suit my purpose and
may be be less "clean" to implement. I don't know if the name is appropriate
but there is a 'integer divide by 2' part in the code so I thought "What the
heck, why not!".

Any feedback is appreciated.

Yours Truly
Mike

vulcan at win.co.nz

global function binary_find(object element, sequence list)
 -- find element in list, same as find()
 integer start, finish, low, high, range, jump, d

 start=1
 finish=length(list)

 low=start
 high=finish

 while 1 do
  range=high - low

  if range < 2 then
   d = find(element, list[low..high])
   if d then d += low - 1 end if
   return d
  else
   jump=floor(range/2)
   d=compare(element, list[low + jump])

   if d=1 then -- search higher
    low += jump
    if low > finish then
     return 0
    end if
   elsif d=-1 then -- search lower
    high=low + jump
   else -- a hit!
    return low + jump
   end if
  end if
 end while
 return 0
 end function

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu