2016-03-29 41 views
1

以下代码模拟查找最接近的对,但是当我生成大于250的随机数量的对时,它会引发堆栈溢出错误。但250对和任何偶数量似乎都没有问题。有任何想法吗?为什么我收到堆栈溢出错误?

错误发生在if语句下ComparePoints的递归调用中。

public class Divide { 

    Point2D closest1; 
    Point2D closest2; 
    double Distance = Double.MAX_VALUE; 

    public Divide(Point2D[] RandArray){ 
     SortArray s = new SortArray(); 
     RandArray = s.SortPointsX(RandArray); 
     SplitAndConquer(RandArray); 
    } 

    private double ComparePoints(Point2D a, Point2D b, Point2D[] s, 
       int CurrentPoint, int NextPoint){ 
      if(s[CurrentPoint] != null && s[NextPoint] != null){ 
       if (Distance > a.distance(b) && 
         (a.getX() != b.getX() || a.getY() != b.getY())){ 
        Distance = a.distance(b); 
        closest1 = new Point2D.Double(a.getX(), a.getY()); 
        closest2 = new Point2D.Double(b.getX(), b.getY()); 
       } 
       if (NextPoint == (s.length - 1)){ 
        NextPoint = s.length - ((s.length - 1) - CurrentPoint); 
        CurrentPoint++; 
       } 
       if (CurrentPoint != (s.length - 1)){ 
        if (NextPoint != (s.length - 1)){ 
        NextPoint++; 
        ComparePoints(s[CurrentPoint], s[NextPoint], 
          s, CurrentPoint, NextPoint); 
        } 
       } 
       if (CurrentPoint == (s.length - 1)){ 
        CurrentPoint = 0; 
        NextPoint = 0; 
       } 
      } 
     return Distance; 
    } 

    private void SplitAndConquer(Point2D[] RandArray){ 
     double median = RandArray[RandArray.length/2].getX(); 
     int countS1 = 0; 
     int countS2 = 0; 
     boolean exact = false; 
     int CurrentPoint = 0; 
     int NextPoint = 0; 
     Point2D[] s1 = new Point2D[RandArray.length/2]; 
     Point2D[] s2 = new Point2D[RandArray.length/2]; 

     for (int i = 0; i < RandArray.length; i++){ 

      if (RandArray[i].getX() < median){ 
       s1[countS1] = RandArray[i]; 
       countS1++; 
      } 
      else if (RandArray[i].getX() > median){ 
       s2[countS2] = RandArray[i]; 
       countS2++; 
      } 
      else if (RandArray[i].getX() == median && exact == false){ 
       s2[countS2] = RandArray[i]; 
       exact = true; 
       countS2++; 
      } 
      else if (RandArray[i].getX() == median && exact == true) { 
       s1[countS1] = RandArray[i]; 
       exact = false; 
       countS2++; 
      } 
     } 

     if (s1[0] != null && s1[1] != null){ 
      Distance = ComparePoints(s1[0], s1[1], s1, 
        CurrentPoint, NextPoint); 
      Distance = ComparePoints(s2[0], s2[0], s2, 
        CurrentPoint, NextPoint); 
      }else{ 
       System.out.println 
       ("One of the subsets does not contain enough points!"); 
      } 
     CheckMid(RandArray, Distance, median, CurrentPoint, NextPoint); 
     PrintClosest(); 
     } 

    private void PrintClosest() { 
     System.out.println("The closest pair found using Divide " 
       + "And Conquer is at (" 
       + closest1.getX() + " " + closest1.getY() + "), and (" 
       + closest2.getX() + " " + closest2.getY() + ")"); 
     System.out.println("The distance between the pairs is: " + Distance); 

    } 

    private void CheckMid(Point2D[] randArray, double d, double m, 
      int current, int next) { 
     int MidCount = 0; 
     Point2D[] MidArray = new Point2D[randArray.length]; 
     for(int i = 0; i < randArray.length; i++){ 
      if(randArray[i].getX() > (m - d) && 
        randArray[i].getX() < (m + d)){ 
       MidArray[MidCount] = randArray[i]; 
       MidCount++; 
      } 
     } 
     if (MidArray[0] != null && MidArray[1] != null){ 
     ComparePoints(MidArray[0], MidArray[1], MidArray, 
       current, next); 
     } 
    } 
} 
+0

“但是当我生成大于250的随机数量的对时,它会抛出堆栈溢出错误” - 任何堆栈都是有限大小。要么增加大小,要么改变算法。 –

+0

我想尝试和改变算法,但我不知道如何去做,有什么建议吗? –

回答

1

听起来你超出了为你的程序分配的栈内存量。您可以使用-Xss选项更改堆栈大小。 E.g java -Xss 8M将堆栈大小更改为8MB并运行您的程序。

+0

有没有办法改变程序以适应大量的递归调用而不改变堆栈大小? –

0

内部Java有调用堆栈,它将方法调用存储为堆栈帧。它以LIFO方式处理这些方法调用(帧)。当一个新线程被创建时(在你的情况下是一个主线程),一个固定数量的堆栈和堆内存被分配给该线程。因此,无论何时调用堆栈耗尽,我们都会遇到一个stackoverflow错误。 在你的情况下,递归调用的数量超过了调用堆栈的大小,所以你得到错误。