All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src-lib.atlas.lib.Alg Maven / Gradle / Ivy

There is a newer version: 0.8.10
Show newest version
/*
 * (c) Copyright 2007, 2008, 2009 Hewlett-Packard Development Company, LP
 * All rights reserved.
 * [See end of file]
 */

package atlas.lib;

import java.nio.IntBuffer;
import java.util.Comparator;
import java.util.List;

public class Alg
{
    // Linear search is really there to test binary search.
    static int linearSearch(IntBuffer buff, int key)
    { 
        return linearSearch(buff, 0, buff.limit(), key) ;
    }

    static int linearSearch(IntBuffer buff, int low, int high, int key)
    {
        int len = buff.limit(); // In int units.
        check(len, low, high) ;
        for ( int i = low ; i < high ; i++ )
        {
            int k2 = buff.get(i) ;
            if ( k2 == key )
                return i ;
            if ( k2 > key )
                return encodeIndex(i) ;
        }
        return encodeIndex(high) ;
    }
    
    // The encoded offset (insertion point) when not found.
    public static final int encodeIndex(int i) { return -(i+1) ; } 
    public static final int decodeIndex(int i) { return -(i+1) ; } 

    
    /* Both Arrays and Collections have a binary search implementation.
     * Arrays searches Object[] arrays, and Collections searches List
     *
     * But sometime things are not so easy, and it isn't neat as to
     * what is being searched, like a slice of an NIO Buffer
     * 
     * http://en.wikipedia.org/wiki/Binary_search
     */
    
    public static int binarySearch(IntBuffer buff, int value)
    {
        return  binarySearch(buff, 0, buff.limit(), value) ;
    }
    
    public static int binarySearch(IntBuffer buff, int low, int high, int value)
    {
        // Low is inclusive, high is exclusive.
        check(buff.limit(), low, high) ;
        high -- ;   // Convert high to inclusive.

        // Non-tail-recursive form, because tail-recursion removal
        // is not required by java (unlike scheme).
        
        while (low <= high)
        {
            int mid = (low + high) >>> 1 ;  // int divide by 2 : better: mid = low + ((high - low) / 2)
            int k = buff.get(mid) ;
            
            // Two comparisons : see wikipedia for one comparison version.
            if (k < value)
                low = mid + 1 ;
            else if ( k > value)
                high = mid - 1 ;
            else
                return mid ;
        }
        // On exit, when not finding, low is the least value
        // above, including off the end of the array.  
        return encodeIndex(low) ;
    }
    
    // Alt form - no early termination.
//    public static int binarySearch2(IntBuffer buff, int value, int low, int high)
//    {
//        // Low is inclusive, high is exclusive
//        check(buff.limit(), low, high) ;
//        int N = high ;
//        
//        // Uses high as exclusive index
//        while (low < high)
//        {
//            int mid = (low + high) >>> 1 ;  // int divide by 2 : better: mid = low + ((high - low) / 2)
//            int k = buff.get(mid) ;
//            
//            // Two comparisons : see wikipedia for one comparison version.
//            if ( k < value)
//                low = mid + 1 ;
//            else 
//                //can't be high = mid-1: here A[mid] >= value,
//                //so high can't be < mid if A[mid] == value
//                high = mid;
//        }
//        if (low < N && buff.get(low) == value )
//            return low ;
//        else
//            return enc(low) ;
//    }
        
    private static void check(int len, int low, int high)
    {
        if ( low > high )
            throw new IllegalArgumentException("Low index ("+low+") is not less than high index ("+high+")") ; 
        if ( low < 0 )
            throw new ArrayIndexOutOfBoundsException("Low index is negative: "+low) ; 
        if ( high > len )
            throw new ArrayIndexOutOfBoundsException("High index is too large: "+high) ;
    }

    // Why isn't this in the java RT?
    public static  int binarySearch( List array, int low, int high, T value, Comparator comparator )
    {
        check(array.size(), low, high) ;
        high -- ;

        while( low <= high )
        {
            int mid = ( low + high ) >>> 1 ;

            T k = array.get(mid) ;
            
            int x = comparator.compare(k, value) ;
            if ( x < 0 )
                low = mid + 1 ;
            else if ( x > 0 )
                high = mid - 1 ;
            else
                return mid ;
        }
        return encodeIndex(low) ;
    }

    // Why isn't this in the java RT?
    public static >
    int binarySearch(T[] array, int low, int high, T value)
    {
        check(array.length, low, high) ;
        high -- ;

        while( low <= high )
        {
            int mid = ( low + high ) >>> 1 ;

            T k = array[mid] ;
            
            int x = k.compareTo(value) ; // comparator.compare(k, value) ;
            if ( x < 0 )
                low = mid + 1 ;
            else if ( x > 0 )
                high = mid - 1 ;
            else
                return mid ;
        }
        return encodeIndex(low) ;
    }
    
    
    // Use Arrays.binarySearch functions
    
//    public static int binarySearch(int buff[], int value)
//    { return binarySearch(buff, value, 0, buff.length) ; } 
//
//    public static int binarySearch(int buff[], int low, int high, int value)
//    {
//        check(buff.length, low, high) ;
//        // Low is inclusive, high is exclusive.
//        high -- ;   // Convert high to inclusive.
//
//        // Non-tail-recursive form, because tail-recursion removal
//        // is not required by java (unlike scheme).
//        
//        while (low <= high)
//        {
//            int mid = (low + high) >>> 1 ;  // int divide by 2 
//            int k = buff[mid] ;
//
//            if (k < value)
//                low = mid + 1 ;
//            else if ( k > value)
//                high = mid - 1 ;
//            else
//                return mid ;
//        }
//        // On exit, when not finding, low is the least value
//        // above, including off the end of the array.  
//        return encodeIndex(low) ;
//    }
//
//    
//    public static int binarySearch(long buff[], int value)
//    { return binarySearch(buff, value, 0, buff.length) ; } 
//    
//    public static int binarySearch(long buff[], int low, int high, long value)
//    {
//        check(buff.length, low, high) ;
//        // Low is inclusive, high is exclusive.
//        high -- ;   // Convert high to inclusive.
//
//        // Non-tail-recursive form, because tail-recursion removal
//        // is not required by java (unlike scheme).
//        
//        while (low <= high)
//        {
//            int mid = (low + high) >>> 1 ;  // int divide by 2 
//            long k = buff[mid] ;
//
//            if (k < value)
//                low = mid + 1 ;
//            else if ( k > value)
//                high = mid - 1 ;
//            else
//                return mid ;
//        }
//        // On exit, when not finding, low is the least value
//        // above, including off the end of the array.  
//        return encodeIndex(low) ;
//    }
}

/*
 * (c) Copyright 2007, 2008, 2009 Hewlett-Packard Development Company, LP
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */




© 2015 - 2025 Weber Informatics LLC | Privacy Policy