0

The filepointer gets stuck at a point resulting in a StackOverflowError. Can you point me to what exactly is wrong here? The error exactly is: java.lang.StackOverflowError

I am doing a seek to find the location as record width is not fixed.

Here is the piece of code:

private static void binarySearch(RandomAccessFile raf, String searchvalue, Long low, Long high) throws IOException
{
    Long middle = (low + high) / 2;
    Long mreal = null;
    if(low > raf.length() -1 || high > raf.length()-1 || low >= high) {
        System.out.println("Element not found:");   return ;
    }

    StringBuilder sb = new StringBuilder();
    for(long filePointer = middle; filePointer != -1; filePointer--) {
        raf.seek(filePointer);
        int readByte = raf.readByte();
        if(readByte == 0xA) {
            break;
        }

        sb.append((char)readByte);
    }

    String lastLine = sb.reverse().toString();
    System.out.println(lastLine);

    mreal = raf.getFilePointer();
    String str = raf.readLine();
    System.out.println(str);

    String values[] = str.split("\t",-1);
    int compared = searchvalue.compareTo(values[fieldindex]);
    System.out.println(fieldindex);

    if(compared == 0) {
        System.out.println("Value found. The other details:");
        for(int i=0; i < values.length;i++)
        System.out.print("\t" +  values[i]);
        return;
    } else if(compared < 0)
        binarySearch(raf,searchvalue,low,mreal-1);
    else if(compared > 0)
        binarySearch(raf,searchvalue,mreal,high);
}

Stack trace:

Exception in thread "main" java.lang.StackOverflowError

>at java.util.regex.Pattern$Node.<init>(Pattern.java:2993)
    >at java.util.regex.Pattern$CharProperty.<init>(Pattern.java:3332)
    >at java.util.regex.Pattern$CharProperty.<init>(Pattern.java:3332)
    >at java.util.regex.Pattern$BmpCharProperty.<init>(Pattern.java:3363)
    >at java.util.regex.Pattern$BmpCharProperty.<init>(Pattern.java:3363)
    >at java.util.regex.Pattern$Single.<init>(Pattern.java:3391)
    >at java.util.regex.Pattern.newSingle(Pattern.java:2951)
    >at java.util.regex.Pattern.atom(Pattern.java:1985)
    >at java.util.regex.Pattern.sequence(Pattern.java:1885)
    >at java.util.regex.Pattern.expr(Pattern.java:1752)
    >at java.util.regex.Pattern.compile(Pattern.java:1460)
    >at java.util.regex.Pattern.<init>(Pattern.java:1133)
    >at java.util.regex.Pattern.compile(Pattern.java:823)
    >at java.lang.String.split(String.java:2292)
4

1 回答 1

0
else if(compared > 0)
    binarySearch(raf,searchvalue,mreal,high);

那应该是mreal + 1。

此外,递归对于二分搜索来说是多余的......通常循环更快。

罗尔夫

编辑:====

好的,所以它仍然不起作用。这是因为我只说对了一部分。我只看了一会儿代码就发现了问题,但后来我用错误的值修复了它。

而不是添加 1,您应该添加您比较的字符串中的字符数,加上行终止符(如果有的话 - 它可能是最后一行......)。

这整件事告诉我的是,这可能是家庭作业……以及递归练习和二分搜索研究。

不为你做功课,我会花一点时间批评你的代码。

二分查找应该是找到中点,如果中点匹配,则返回,如果大于搜索,则在中点之前搜索,否则在中点之后搜索。

您的代码正在获得中点“正确”和“之前”正确,但它没有搜索“之后”......因为您没有正确计算“之后”部分..您需要在“之后”整个字符串,而不仅仅是在第一个字符之后。修理它。请记住,使用 readLine() 意味着您不知道行终止符(是 '\r\n' 还是只是 '\n'?)。我建议在“中间”点之后使用一个循环,然后自己向前走,直到到达另一个 \n,然后在需要时使用该 (+1) 来计算“之后”搜索的位置。

其他一些评论......

  • 不要使用“自动装箱”。使用 long 原语而不是 Long 对象。
  • 为什么在变量'filepointer'中已经知道它返回的值时调用getFilePointer()。
  • 计算“中间”时,使用低 + 高 >>> 1 .... 它会给您的讲师留下深刻印象,您可以在阅读此内容后说您知道原因:http: //googleresearch.blogspot.ca/2006/06/ extra-extra-read-all-about-it-nearly.html
  • 当你阅读这篇文章时,你会明白为什么在循环中进行二分搜索比在递归中进行更好。
  • 如果您确实使用递归,则应该将参数设置为“最终”,因为这会在堆栈上留下更小的足迹,并且您可以“更深”。
  • 如果你确实使用递归,那么你应该最小化你在你的方法中创建的对象......比如 StringBuilders......

罗尔夫

于 2013-01-18T04:52:22.780 回答