Search code examples
javasearchbinaryrandomaccessfile

Binary search of a RandomAccessFile


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

Solution

  • 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;
                }