Java 不一致的堆栈溢出
Java Inconsistent Stack Overflow
我一直在为我的 AP 计算机科学 class 做我的期末项目,并且正在修改 AP Picture Lab 来完成它(所有源代码都可以在 https://github.com/jvperrin/ap-picture-lab 获得)。
对于我项目的一部分,我实施了深度优先搜索以获取黑色目标像素的相邻像素。但是,似乎每隔一段时间我 运行 程序都会出现堆栈溢出错误,或者程序运行良好。我遇到这个问题是有原因的吗?它与 Java 存储堆栈内存的方式有关吗?
错误信息
Exception in thread "main" java.lang.WhosebugError
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)
....
Z图片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;
}
}
(我在别处有一个main方法实例化一个ZPicture并调用findletters)。
WhosebugError
是由递归调用引起的(这甚至不是必需的)。错误的原因很简单:对于堆栈中的每个元素,算法都会进行另一个递归调用。如果黑色像素的面积足够大,相邻黑色像素的个数就会超过stack-size,造成WhosebugError
。好消息:递归调用在这里没有任何意义,因为您已经使用了堆栈。只需将其删除,代码就可以正常工作了。
我一直在为我的 AP 计算机科学 class 做我的期末项目,并且正在修改 AP Picture Lab 来完成它(所有源代码都可以在 https://github.com/jvperrin/ap-picture-lab 获得)。
对于我项目的一部分,我实施了深度优先搜索以获取黑色目标像素的相邻像素。但是,似乎每隔一段时间我 运行 程序都会出现堆栈溢出错误,或者程序运行良好。我遇到这个问题是有原因的吗?它与 Java 存储堆栈内存的方式有关吗?
错误信息
Exception in thread "main" java.lang.WhosebugError
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)
....
Z图片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;
}
}
(我在别处有一个main方法实例化一个ZPicture并调用findletters)。
WhosebugError
是由递归调用引起的(这甚至不是必需的)。错误的原因很简单:对于堆栈中的每个元素,算法都会进行另一个递归调用。如果黑色像素的面积足够大,相邻黑色像素的个数就会超过stack-size,造成WhosebugError
。好消息:递归调用在这里没有任何意义,因为您已经使用了堆栈。只需将其删除,代码就可以正常工作了。