private boolean[][] computeMainOutline(boolean[][] outline) {
int pixelValue[][] = new int [width][height];
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
if(pixelValue[x][y] == 0) {
ArrayList<Point2D.Double> path = new ArrayList<>();
findPath(x, y, outline, pixelValue, path);
}
return new boolean[1][1]; // to avoid compilation error
}
private void findPath(int x, int y, boolean[][] outline, int pixelValue [][], ArrayList<Point2D.Double> path) {
path.add(new Point2D.Double(x, y));
if(x > 0 && outline[x - 1][y] == true) // check right
findPath(x - 1, y, outline, pixelValue, path);
if(x < width && outline[x + 1][y] == true) // check left
findPath(x + 1, y, outline, pixelValue, path);
if(y < height && outline[x][y + 1] == true) // check up
findPath(x, y + 1, outline, pixelValue, path);
if(y > 0 && outline[x][y - 1] == true) // check down
findPath(x, y - 1, outline, pixelValue, path);
}
上記のメソッドはStackOverflowError
を与えていますが、なぜわかりません。再帰的なスタックオーバーフローと奇数オブジェクトの参照Java
方法computeMainOutline
は、outline
アレイ全体と同じサイズのpixelValue
アレイ全体を反復します。特定の座標に対して「値」が計算されていない場合、findPath
関数はパスを再帰的に計算します。パスは、基本的に、どれくらいの数の「真の」配列要素が互いに隣り合っているかです。値を計算するメソッドは追加されませんが、私の最初の問題はパスを見つけることです。
path.add(new Point2D.Double(x, y));
の直後にprintステートメントを入れて、再帰的メソッド内にpath.size()
を印刷すると、サイズのシーケンスが一貫して印刷されない(1,2,3,4,2,3,4)、なぜですか?あなたは再帰を行っている方法が間違っている...
private boolean[][] computeMainOutline(boolean[][] outline) {
int pixelValue[][] = new int [width][height];
boolean visited[][] = new boolean[width][height];
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
if(visited[x][y] == false) {
ArrayList<Point2D.Double> path = new ArrayList<>();
findPath(x, y, outline, pixelValue, path, visited);
}
return new boolean[1][1]; // to avoid compilation error
}
private void findPath(int x, int y, boolean[][] outline, int pixelValue [][], ArrayList<Point2D.Double> path, boolean visited [][]) {
path.add(new Point2D.Double(x, y));
visited[x][y] = true;
if(x > 0 && visited[x - 1][y] == false && outline[x - 1][y] == true) // check right
findPath(x - 1, y, outline, pixelValue, path, visited);
if(x < width - 1 &&visited[x + 1][y] == false && outline[x + 1][y] == true) // check left
findPath(x + 1, y, outline, pixelValue, path, visited);
if(y < height - 1 && visited[x][y + 1] == false && outline[x][y + 1] == true) // check up
findPath(x, y + 1, outline, pixelValue, path, visited);
if(y > 0 && visited[x][y - 1] == false && outline[x][y - 1] == true) // check down
findPath(x, y - 1, outline, pixelValue, path, visited);
}
既に訪問したアウトライン要素をマークしないと、同じポイントにパスを追加するため、findPathは無限に再読みされます – csharpfolk