Java分治算法堆栈溢出错误

Java分治算法堆栈溢出错误,java,arrays,stack-overflow,divide-and-conquer,Java,Arrays,Stack Overflow,Divide And Conquer,我正在尝试使用divide and conquer查找整数数组中最小数字的索引,但出现以下堆栈溢出错误: Exception in thread "main" java.lang.StackOverflowError at java.lang.StrictMath.floor(Unknown Source) at java.lang.Math.floor(Unknown Source) 这是我的分而治之的方法: private static int dC(int[] a, in

我正在尝试使用divide and conquer查找整数数组中最小数字的索引,但出现以下堆栈溢出错误:

Exception in thread "main" java.lang.StackOverflowError
    at java.lang.StrictMath.floor(Unknown Source)
    at java.lang.Math.floor(Unknown Source)
这是我的分而治之的方法:

private static int dC(int[] a, int f, int l) {
        if(f == 1)
            return f;
        if(a[dC(a, f, (int)(Math.floor((double)(f+l)/2)))] > a[dC(a, (int)(Math.floor((double)(f+l)/2)+1), l)])
            return dC(a, (int)(Math.floor((double)(f+l)/2)+1), l);
        else
            return dC(a, f, (int)(Math.floor((double)(f+l)/2)));
    }
以下是我在主要方法中的内容:

int[] a = {35,30,40,50};

System.out.println(dC(a, 0, 3));

你的停止“规则”有问题


你的停止“规则”有问题


这就是经典的二进制搜索问题。通过查看您的代码,我可以了解到,您似乎陷入了对当前数组的左、右子数组进行每次递归调用所使用的逻辑中。我在下面使用的逻辑是,对于左递归,从开始到(开始+结束)/2,对于右递归,从((开始+结束)/2)+1到结束。这保证了不会有任何重叠

当算法发现自己位于数组中的单个条目上时,就会出现基本情况。在本例中,我们只返回该值,不进一步递归

private static int dC(int[] a, int start, int end) {
    if (start == end) return a[start];

    int left = dC(a, start, (start+end)/2);
    int right = dC(a, ((start+end)/2) + 1, end);

    return left < right ? left : right;
}

public static void main(String args[])
{
    int[] a = {10, 3, 74, 0, 99, 9, 13};
    System.out.println(dC(a, 0, 6));   // prints 0
}
private static int dC(int[]a,int start,int end){
if(start==end)返回一个[start];
int left=dC(a,开始,(开始+结束)/2);
int right=dC(a,((开始+结束)/2)+1,结束);
返回左<右?左:右;
}
公共静态void main(字符串参数[])
{
int[]a={10,3,74,0,99,9,13};
System.out.println(dC(a,0,6));//打印0
}


注意:我不知道Math.floor将扮演什么角色,因为您使用的是整数数组,而不是双精度或浮点数。我删除了这个,因为我认为没有必要使用它。

这只是经典的二进制搜索问题。通过查看您的代码,我可以了解到,您似乎陷入了对当前数组的左、右子数组进行每次递归调用所使用的逻辑中。我在下面使用的逻辑是,对于左递归,从开始到(开始+结束)/2,对于右递归,从((开始+结束)/2)+1到结束。这保证了不会有任何重叠

当算法发现自己位于数组中的单个条目上时,就会出现基本情况。在本例中,我们只返回该值,不进一步递归

private static int dC(int[] a, int start, int end) {
    if (start == end) return a[start];

    int left = dC(a, start, (start+end)/2);
    int right = dC(a, ((start+end)/2) + 1, end);

    return left < right ? left : right;
}

public static void main(String args[])
{
    int[] a = {10, 3, 74, 0, 99, 9, 13};
    System.out.println(dC(a, 0, 6));   // prints 0
}
private static int dC(int[]a,int start,int end){
if(start==end)返回一个[start];
int left=dC(a,开始,(开始+结束)/2);
int right=dC(a,((开始+结束)/2)+1,结束);
返回左<右?左:右;
}
公共静态void main(字符串参数[])
{
int[]a={10,3,74,0,99,9,13};
System.out.println(dC(a,0,6));//打印0
}


注意:我不知道Math.floor将扮演什么角色,因为您使用的是整数数组,而不是双精度或浮点数。我删除了它,因为我认为没有必要使用它。

这是一个典型的问题,将索引定位到
min/max
,您可以尝试如下操作:

public static void main(String... args) {
    int[] arr = generateArrays(100, 1000, 0, 10000, true);
    int minIndex = findMinIndex(arr, 1, arr.length - 1);
    int theMin = arr[minIndex];
    Arrays.sort(arr);
    System.out.println(String.format("The min located correctly: %s", arr[0] == theMin));
}

private static int findMinIndex(int[] a, int l, int r) {
    if (r - l < 1) return l;
    int mid = l + (r - l) / 2;
    int lIndex = findMinIndex(a, l + 1, mid);
    int rIndex = findMinIndex(a, mid + 1, r);
    int theMinIndex = l;
    if (a[lIndex] < a[theMinIndex]) theMinIndex = lIndex;
    if (a[rIndex] < a[theMinIndex]) theMinIndex = rIndex;
    return theMinIndex;
}
publicstaticvoidmain(字符串…参数){
int[]arr=generatarrays(100,1000,0,10000,真);
int minIndex=findMinIndex(arr,1,arr.length-1);
int theMin=arr[minIndex];
数组。排序(arr);
System.out.println(String.format(“正确定位的最小值:%s”,arr[0]==theMin));
}
私有静态int findMinIndex(int[]a,int l,int r){
如果(r-l<1)返回l;
int mid=l+(r-l)/2;
int-lIndex=findMinIndex(a,l+1,mid);
int-rIndex=findMinIndex(a,mid+1,r);
int最小指数=l;
如果(a[lIndex]
和助手生成一个随机数组

public static int[] generateArrays(int minSize, int maxSize, int low, int high, boolean isUnique) {
    Random random = new Random(System.currentTimeMillis());
    int N = random.nextInt(maxSize - minSize + 1) + minSize;
    if (isUnique) {
        Set<Integer> intSet = new HashSet<>();
        while (intSet.size() < N) {
            intSet.add(random.nextInt(high - low) + low);
        }
        return intSet.stream().mapToInt(Integer::intValue).toArray();
    } else {
        int[] arr = new int[N];
        for (int i = 0; i < N; ++i) {
            arr[i] = random.nextInt(high - low) + low;
        }
        return arr;
    }
}
public static int[]generatarrays(int-minSize、int-maxSize、int-low、int-high、boolean-isUnique){
Random Random=新随机(System.currentTimeMillis());
int N=random.nextInt(maxSize-minSize+1)+minSize;
如果(是唯一的){
Set intSet=new HashSet();
while(intSet.size()
将索引定位到
min/max
是一个典型的问题,您可以通过以下方式进行尝试:

public static void main(String... args) {
    int[] arr = generateArrays(100, 1000, 0, 10000, true);
    int minIndex = findMinIndex(arr, 1, arr.length - 1);
    int theMin = arr[minIndex];
    Arrays.sort(arr);
    System.out.println(String.format("The min located correctly: %s", arr[0] == theMin));
}

private static int findMinIndex(int[] a, int l, int r) {
    if (r - l < 1) return l;
    int mid = l + (r - l) / 2;
    int lIndex = findMinIndex(a, l + 1, mid);
    int rIndex = findMinIndex(a, mid + 1, r);
    int theMinIndex = l;
    if (a[lIndex] < a[theMinIndex]) theMinIndex = lIndex;
    if (a[rIndex] < a[theMinIndex]) theMinIndex = rIndex;
    return theMinIndex;
}
publicstaticvoidmain(字符串…参数){
int[]arr=generatarrays(100,1000,0,10000,真);
int minIndex=findMinIndex(arr,1,arr.length-1);
int theMin=arr[minIndex];
数组。排序(arr);
System.out.println(String.format(“正确定位的最小值:%s”,arr[0]==theMin));
}
私有静态int findMinIndex(int[]a,int l,int r){
如果(r-l<1)返回l;
int mid=l+(r-l)/2;
int-lIndex=findMinIndex(a,l+1,mid);
int-rIndex=findMinIndex(a,mid+1,r);
int最小指数=l;
如果(a[lIndex]
和助手生成一个随机数组

public static int[] generateArrays(int minSize, int maxSize, int low, int high, boolean isUnique) {
    Random random = new Random(System.currentTimeMillis());
    int N = random.nextInt(maxSize - minSize + 1) + minSize;
    if (isUnique) {
        Set<Integer> intSet = new HashSet<>();
        while (intSet.size() < N) {
            intSet.add(random.nextInt(high - low) + low);
        }
        return intSet.stream().mapToInt(Integer::intValue).toArray();
    } else {
        int[] arr = new int[N];
        for (int i = 0; i < N; ++i) {
            arr[i] = random.nextInt(high - low) + low;
        }
        return arr;
    }
}
public static int[]generatarrays(int-minSize、int-maxSize、int-low、int-high、boolean-isUnique){
Random Random=新随机(System.currentTimeMillis());
int N=random.nextInt(maxSize-minSize+1)+minSize;
如果(是唯一的){
Set intSet=new HashSet();
while(intSet.size()
只需检查二进制搜索的源代码,并以此为基础编写自己的代码。无关:使用有意义的名称。a、 他们都毫无意义。编写代码不是为了让编译器运行