This is a method that searches for a target number in a RandomAccessFile using a binary search. It deals exclusively with integers. I have every set up, but I'm getting the wrong numbers. Since a raf contains bytes, and an integer contains four bytes, I thought I'd just decrement the high by 4 and increment the low by 4 where the same operations were done by 1 in a regular binary search. Apparently this is not the case, and I'm having a hard time wrapping my head around binary I/O in general. Help?
//determines if a target number is in a RandomAccessFile using a binary search
//tracks the number of times it took to find that the number was/wasn't in the file
public static void binarySearch(){
Scanner input = new Scanner(System.in);
int target = 0; //the number being searched for
boolean targetFound = false; //indicates if the target is found
int searchCount = 0; //the number of times it took to find that the number was/wasn't in the file
System.out.print("Please enter the number you wish to search for: ");
target = input.nextInt();
try{
RandomAccessFile raf = new RandomAccessFile("Project10.dat", "r");
long low = 0;
long high = raf.length() - 1;
int cur = 0;
while(high >= low){
long mid = (low + high) / 2;
raf.seek(mid);
cur = raf.readInt();
System.out.println(cur); //for debugging
searchCount++;
if(target < cur){
high = mid - 4;
}
else if(target == cur){
targetFound = true;
break;
}
else{
low = mid + 4;
}
}
raf.close();
}
catch(FileNotFoundException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
if(targetFound == true){
System.out.println("The number " + target + " is in the file. It took " + searchCount + " tries to discover this.");
}
else{
System.out.println("The number " + target + " is not in the file. It took " + searchCount + " tries to discover this.");
}
}//end method binarySearch
an int is 4 bytes so say your file contains the numbers 1... 20 The the raf.length is 80 (not 20) i.e. 4* 20 You have the right lines, but need to work in terms of 4 your high value in this case is 79 rather than 76 (using example above) so high should be length - 4
you can try: low = 0;
long high = (raf.length() / 4) - 1 // this is in terms of elements
long mid = (low + high) / 2 ... again element rather than where in byte array
raf.seek(mid * 4) // You can use the *4 to access the correct location in bytes
cur = raf.readInt()
if(target < cur){
high = mid - 1;
}
else if(target == cur){
targetFound = true;
break;
}
else{
low = mid + 1;
}