1.1.29等值键。为BinarySearch类添加一个静态方法rank(),它接受一个键和一个整型有序数组(可能存在重复键)作为参数并返回数组中小于该键的元素数量,以及一个类似的方法count()来返回数组中等于该键的元素的数量。注意:如果i和j分别是rank(key,a)和count(key,a)的返回值,那么a[i...i+j-1]就是数组中所有和key相等的元素。
import java.util.Arrays;
public class BinarySearch
{
public static void main(String[] args)
{
int[] whitelist=In.readInts(args[0]);
Arrays.sort(whitelist);
while (!StdIn.isEmpty())
{
int key=StdIn.readInt();
StdOut.printf("small "+ Integer.toString(key) + " num=%d ,count=%d",rank(key,whitelist),count(key,whitelist));
}
}//end main
public static int rank(int key,int[] a)
{
int smallCount=findSmallKeyIndex(key,a);
if (smallCount<1) return 0;
else return smallCount;
}//end rank
public static int count(int key,int[] a)
{
int smallKeyIndex=findSmallKeyIndex(key,a);
int bigKeyIndex=findBigKeyIndex(key,a);
if (smallKeyIndex==-1) return 0;
else return bigKeyIndex-smallKeyIndex+1;
}//end count
public static int findSmallKeyIndex(int key,int[] a)
{
int indexOfKey=findKeyIndex(key,a);
//key‘s index is 0 or -1 then no one is small than the key.
if (indexOfKey==-1 )
return -1;
else if(indexOfKey==0)
return 0;
else //(indexOfKey>0)
{
indexOfKey--;
//find to 0
while (indexOfKey>=0 && a[indexOfKey]==key) indexOfKey--;
if (indexOfKey>0) return indexOfKey+1;
else if(indexOfKey==0 && a[indexOfKey]<key) return indexOfKey+1;
else//(indexOfKey==0 && a[indexOfKey]==key)
return 0;
}
}//end findSmallKeyIndex
public static int findBigKeyIndex(int key,int[] a)
{
int indexOfKey=findKeyIndex(key,a);
//not found or found the last then no one is big than the key.
if (indexOfKey==-1)
return -1;
else if(indexOfKey==a.length-1)
return indexOfKey;
//find to end
else //(indexOfKey>=0 && indexOfKey<a.length-1)
{
indexOfKey++;
while(indexOfKey<a.length && a[indexOfKey]==key) indexOfKey++;
if(indexOfKey<a.length-1) return indexOfKey-1;
else if(indexOfKey==a.length-1 && a[indexOfKey]>key) return indexOfKey-1;
else//(indexOfKey==a.length-1 && a[indexOfKey]==key)
return a.length-1;
}
}//findBigKeyIndex
public static int findKeyIndex(int key,int[]a)
{
int lo=0;
int hi=a.length-1;
while (lo<=hi)
{
int mid=lo+(hi-lo)/2;
if (key<a[mid]) hi=mid-1;
else if(key>a[mid]) lo=mid+1;
else return mid;
}
return -1;
}//findKey
}