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);
        }
    }
}
4

2 に答える 2

1

プログラムに割り当てられたスタック メモリの量を超えているようです。-Xss オプションでスタックサイズを変更できます。たとえばjava -Xss 8M、スタック サイズを 8MB に変更してプログラムを実行します。

于 2016-03-29T03:26:03.087 に答える
0

内部的に Java には、メソッド呼び出しをスタック フレームとして格納するコール スタックがあります。そして、これらのメソッド呼び出し (フレーム) を LIFO 方式で処理します。新しいスレッド(あなたの場合はメインスレッド)が作成されると、固定量のスタックとヒープメモリがそのスレッドに割り当てられます。そのため、コール スタックが使い果たされるたびに、stackoverflow エラーが発生します。あなたの場合、再帰呼び出しの数が呼び出しスタックのサイズを超えているため、エラーが発生しています。

于 2016-03-29T03:57:14.057 に答える