Re: binary search with reference to append

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

You have misunderstood.

The issues are:

The logic of the input checks is wrong.

The handling of empty sequences is wrong.
(if you haven't searched you haven't got a position,
setting mid to sp is arbitrary,
something is a bit funny at the caller's end)

The principles of design involved are:
caller contracts to provide valid input.
called contracts to provide valid output for valid input.

Therefore

1 Calling bsearch with an empty sequence should return NOT FOUND.
No search was made.

2 Calling bsearch with sp > ep is the same as calling with an
empty sequence.
Returning -sp is simply wrong.

3 Calling bsearch with out of bounds sp, ep should result in
'whatever'. It could crash return a value.
It's the caller's problem.

Most of what I wrote was itemising how things go wrong if bsearch messes with its parameters. And fiddling lo and hi in arbitrary ways is most definitely messing even though sp and ep are not changed.

jaygade said...

Did you mean the caller should check bounds (which is true, IMO) or that the called function should check bounds (which seems to be your example)?

The caller should check.
Here the callee is checking.
The point is that the callee checking creates problems.

said...

Are there any cases where wrong parameters will return erroneous or indeterminate information instead of crashing?

Yes: there are.

said...

If the called function can return bad output for bad inputs, then the called function should be responsible for checking those conditions.

No. that is in contradiction of
the caller should check its inputs.
The called function is at liberty to
plough ahead or whatever.

said...

If the function will cause a crash with bad inputs, then I would suggest that it's the caller's responsibility to ensure that it calls the function with the correct parameters.

Quite so.

said...

I mean, we can fail if sequence A isn't sorted in ascending order. Whose responsibility is it to check that condition? The caller or the called function?

1 Well it would have to be the caller as otherwise there would be
no point in using binary search at all.

2 Binary search does not require a sorted array.
If you consider something like:

   A[lo] < x < A[hi]         -- lo < hi 
   m = mid(lo,hi) 
-- We have one of 
   A[m] = x 
   A[lo] < x < A[m] 
   A[m] < x < A[hi] 

and so on

Binary search is the mean value theorem. Ref:
van Gasteren, Netty; Feijen, Wim (1995).
"The Binary Search Revisited"

    nItems = length(haystack)  
  
    if endp = 0 then  
        hi = nItems  
    else  
        hi = endp  
    end if  
  
    if hi <= nItems and startp <= hi then  
        lo = startp  
    else  
        abort(1)  
    end if  
  
    while lo <= hi do  
        midp = floor((lo + hi) / 2)  
        switch eu:compare(needle, haystack[midp]) do  
          case -1 then hi = midp - 1  
          case 0 then return midp  
          case +1 then lo = midp + 1  
        end case  
    end while  
  
    -- Not found  
    return 0  
said...

If startp > endp, but both are less than nItems, I think that either failure OR returning 0 is a valid response so long as it's documented. Failure could be better during debugging in order to catch invalid inputs when reasonable.

In this case it is reasonable to check the boundaries of the search, but it is not necessarily reasonable to check to see if the haystack is sorted.

This illustrates that the caller should validate the data before sending it to the bsearch function, and that the bsearch function should reject invalid inputs.

You say the caller should validate.
Yet you still insist on bsearch rejecting invalid inputs.
Surely all bsearch needs to do is return correct results for
valid input.

function bsearch(seq A, obj x, int sp, int ep) 
   int lo = sp 
   int hi = ep 
   int m, c 
 
   if length(A) = 0 or sp > ep then return 0 end if 
 
   while lo <= hi do  
      m = floor((lo+hi)/2)  
      c = compare(x, A[m]) 
      switch c do  
      case -1 then hi = m-1  
      case  0 then return m  
      case +1 then lo = m+1  
      end switch  
    end while  
    -- Not found 
    if c = 1 then m = m+1 end if  
    if m > sp and m <= ep then  
       return -m 
    else 
       return 0               -- no position found 
    end if 

Even simpler would be to drop parameters sp, ep altogether
and pass the slice A[sp..ep] and x.

function bsearch(seq A, obj x) 
   int lo = 1 
   int hi = length(A) 
   int m, c 
 
   if hi < lo then return 0 end if 
 
   while lo <= hi do  
      m = floor((lo+hi)/2)  
      c = compare(x, A[m]) 
      switch c do  
      case -1 then hi = m-1  
      case  0 then return m  
      case +1 then lo = m+1  
      end switch  
   end while  
   -- Not found  
   if c > 0 then m = m+1 end if 
   if m > 1 and m <= length(A) then  
      return -m  
    else 
       return 0               -- no position found 
    end if 
new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu