2016-03-29 40 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錯誤。 在你的情況下,遞歸調用的數量超過了調用堆棧的大小,所以你得到錯誤。