用Java实现随机访问文件的二进制搜索

时间:2016-09-10 21:29:49

标签: java binary-search compareto random-access

我正在用Java编写一个程序,用户可以使用随机访问文件创建“数据库”(.txt文件)并在那里存储记录。我正在努力实现二进制搜索,以便为用户提供按ID查找记录的选项。

 public static String binarySearch(String fileName, String id,String data_config) throws IOException 
    {
    RandomAccessFile Din = new RandomAccessFile(fileName, "r");
    num_records = getNumOfRecords(data_config);
    int Low = 0;
    int High = num_records;
    int Middle;
    String MiddleId;
    String record = "NOT_FOUND";
    boolean Found = false;

    while (!Found && (High >= Low)) 
    {
        Middle = (Low + High) / 2;

        record = getRecord(fileName,Middle,data_config);
        MiddleId = record.substring(0,3);
        int result = MiddleId.compareTo(id);


        if (result == 0)   // ids match
            Found = true;
        else if (result < 0)

            Low = Middle + 1;

        else

            High = Middle -1;

    }
    return record;
}

这是getRecord()方法,它工作正常,因为即使没有binarySearch()方法我也测试过它。

   public static String getRecord(String fileName, int recordNum,  String  data_config) throws IOException 
 {
    RandomAccessFile Din = new RandomAccessFile(fileName, "r");
    num_records = getNumOfRecords(data_config);
    String record = "NOT_FOUND";
    if ((recordNum >=1) && (recordNum <= num_records))
    {

        Din.seek(0); // return to the top fo the file
        Din.skipBytes(recordNum * record_size);
        record = Din.readLine();
    }

    return record;
}

问题在于binarySearch中使用的compareTo()方法。它总是返回-1,满足if-else语句的第二部分。 例如,这些是我的一个文件中的记录:

Id体验已婚工资业 0001 1 no 123.0 kjasdhsjhjh
0002 1是123.0 asdhajshjasdhja
0003 1是124.0 ajskjkasjd
0004 1是124.0 kasjdkjsdjs
0005 1是124.0 kajskdjaksdjkas
0006 1是123.0 kjksjdkasj

如果我搜索0001:

高= num_records = 5;

低= 0,因此中= 5/2 = 3

它进入第三条记录并运行0003 compareTo(0001)。这种比较的结果是-1。由于它小于0,因此新的Lo​​w等于Middle + 1 = 3 + 1 = 4,即使它不应该检查第四条记录。由于它是二进制搜索,在这种情况下,它应该检查第二条记录,因为0001小于0003。

你能帮我找一下我做错了吗?

1 个答案:

答案 0 :(得分:0)

请检查:https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring%28int,%20int%29

当您的记录以0003开头时,record.substring(0,3);将返回000,而不是0003.您应该使用record.substring(0,4);来获取ID。