[英]Java: Recursion causes Stack Overflow Error even though code is correct
我正在尝试制作一个程序,该程序通过一个精灵图像,然后使其中的每个形状成为一个新图像。 例如,如果我们拍摄了Mario,我希望帽子是一幅图像,脸部是另一幅图像,依此类推。 我的程序可以在较小的32x32图像上运行,但是如果我想在较大的图像上运行此程序,则会导致堆栈溢出错误。 如果我使用的是C ++,我将通过在每次递归调用后清除堆栈来解决此问题,但据我所知,Java不允许您直接清除堆栈。 我希望我的程序可以在Windows,Linux和Mac上运行,所以我认为Java是最好的选择,所以我真的不想切换我使用的语言。 在Java中的每个递归调用之后,是否可以删除存储在堆栈中的所有内容? 这是我的代码,以防万一出现错误。
private void makeShape(int x, int y)
{
if(x < 0 || y < 0 || y >= sprite.getHeight() || x >= sprite.getWidth())
{
return;
}
if(sample == colorData[y][x] && table[y][x])
{
tempBlankImage[y][x] = sample;
table[y][x] = false;
makeShape(x, y - 1);
makeShape(x, y + 1);
makeShape(x - 1, y);
makeShape(x + 1, y);
}
else
{
return;
}
}
x和y点是通过遍历图像的for循环生成的,并检查是否已将点添加到形状中,如果不是,则根据周围的像素来形成形状。
更新:
private int[][] makeShape(int sample, int x, int y)
{
int[][] tempBlankImage = blankImage();
Queue<Point> queue = new LinkedList<Point>();
queue.add(new Point(x,y));
while(!queue.isEmpty())
{
Point point = queue.remove();
if(sample == colorData[point.y][point.x] && table[point.y][point.x])
{
tempBlankImage[point.y][point.x] = sample;
table[point.y][point.x] = false;
if(point.y < sprite.getHeight() -1)
queue.add(new Point(point.x, point.y+1));
if(point.y > 0)
queue.add(new Point(point.x, point.y-1));
if(point.x < sprite.getWidth()-1)
queue.add(new Point(point.x+1, point.y));
if(point.x > 0)
queue.add(new Point(point.x-1, point.y));
}
}
queue = null;
return tempBlankImage;
}
堆栈溢出错误已停止,现在我已内存不足:Java堆空间,即使我将其增加到2 GB。 我将每个int [] []添加到ArrayList中,我猜这是问题所在。 我还能如何存储数据?
Java是众所周知的,它具有经过自动定义和测试的自动内存管理系统 -即使有可能,也要靠自己管理内存(通常在某种程度上来说)并不是一个好主意。
如果算法执行时间能让您留胡子并能够向大孩子讲述故事,那么清除堆栈将为您带来什么?
不要将其视为递归-考虑算法的某种迭代形式。 例如,您可以遍历所有图像的像素,然后将它们添加到适当的图像(由于其颜色),该图像将存储在某些HashMap中,如此伪代码中所示
HashMap<Color, Image> images= new HashMap<Color, Image>();
for(Pixel pixel : originImage)
Color color = pixel.getColor();
images.get(color).put(pixel)
不要为坏代码而浪费生命
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.