org.apache.jena.atlas.lib.Alg Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena-base Show documentation
Show all versions of jena-base Show documentation
This module contains non-RDF library code and the common system runtime.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.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) ;
// }
}