我一直致力于我的AP计算机科学课程的最终项目,并正在修改AP图片实验室(所有源代码可在https://github.com/jvperrin/ap-picture-lab获得)。
对于我项目的一部分,我实现了深度优先搜索,以获得黑色目标像素的相邻像素。但是,似乎每次运行程序时我都会遇到堆栈溢出错误或程序运行完美。我有没有理由得到这个问题?是否与Java存储堆栈内存有关?
错误消息
Exception in thread "main" java.lang.StackOverflowError
at java.awt.image.ComponentColorModel.getRGB(Unknown Source)
at java.awt.image.BufferedImage.getRGB(Unknown Source)
at SimplePicture.getBasicPixel(SimplePicture.java:300)
at Pixel.getAlpha(Pixel.java:86)
at Pixel.setBlue(Pixel.java:296)
at ZPicture.depthFirstSearch(ZPicture.java:50)
at ZPicture.depthFirstSearch(ZPicture.java:73)
at ZPicture.depthFirstSearch(ZPicture.java:73)
at ZPicture.depthFirstSearch(ZPicture.java:73)
....
ZPicture Class:
import java.util.ArrayList;
import java.util.Stack;
public class ZPicture extends SimplePicture {
protected Pixel[][] pixels;
protected boolean[][] checked;
protected Stack<Pixel> stack;
// a multidimensional array list?!?!
//letters is the pixels in letters
protected ArrayList<ArrayList<Pixel>> letters;
//chars are the key points in letters
protected ArrayList<ZChar> chars;
protected final int BLACK = 30;
protected final int SIZE = 10;
public ZPicture(String fileName) {
super(fileName);
pixels = this.getPixels2D();
checked = new boolean[pixels.length][pixels[0].length];
stack = new Stack<Pixel>();
letters = new ArrayList<ArrayList<Pixel>>();
letters.add(new ArrayList<Pixel>());
chars = new ArrayList<ZChar>();
}
// Z METHODS
public void findLetters() {
// Y
for (int row = 0; row < pixels.length; row++) {
// X
for (int col = 0; col < pixels[0].length; col++) {
Pixel p = pixels[row][col];
if (isBlack(p)) {
stack.push(p);
depthFirstSearch();
}
}
}
sortLetters();
findPoints();
printLetters();
}
protected void depthFirstSearch() {
// base case - if stack has elements
if (!stack.isEmpty()) {
Pixel p = stack.pop();
checked[p.getY()][p.getX()] = true;
letters.get(letters.size() - 1).add(p);
p.setBlue(255);
// get surrounding pixels
Pixel pt = pixels[p.getY() - 1][p.getX()];
Pixel pr = pixels[p.getY()][p.getX() + 1];
Pixel pb = pixels[p.getY() + 1][p.getX()];
Pixel pl = pixels[p.getY()][p.getX() - 1];
// if pixel is black and unchecked, add to stack
if (isBlack(pt)) {
stack.push(pt);
}
if (isBlack(pr)) {
stack.push(pr);
}
if (isBlack(pb)) {
stack.push(pb);
}
if (isBlack(pl)) {
stack.push(pl);
}
// recursion
depthFirstSearch();
} else {
System.out.println("New Letter: " + letters.size());
// note: the final letter is always empty
letters.add(new ArrayList<Pixel>());
}
}
protected boolean isBlack(Pixel p) {
if (p.getBlue() < BLACK && p.getRed() < BLACK && p.getGreen() < BLACK
&& checked[p.getY()][p.getX()] == false) {
return true;
}
return false;
}
}
(我在其他地方有一个实例化ZPicture并调用findletters的主方法。)
答案 0 :(得分:3)
StackOverFlowError
是由递归调用引起的(甚至不需要)。导致错误的原因非常简单:对于堆栈中的每个元素,算法都会进行另一次递归调用。如果黑色像素的面积足够大,则相邻黑色像素的数量将超过堆栈大小,从而导致StackOverFlowError
。好消息:递归调用在这里没有任何意义,因为你已经使用了堆栈。只需删除它,代码应该像魅力一样。