Я пытаюсь создать программу, которая проходит через изображение спрайта, а затем делает каждую фигуру в ней новым изображением. Например, если мы взяли Марио, я хочу, чтобы шляпа была одним изображением, лицо было другим, и так далее. Я получил свою программу для работы с небольшими изображениями 32x32, но если я хочу запустить ее на большом изображении, это приведет к ошибке переполнения стека. Если бы я использовал C++, я бы просто пошел об этом, очистив стек после каждого рекурсивного вызова, но, насколько я знаю, Java не позволяет вам напрямую очищать стек. Я хочу, чтобы моя программа работала на Windows, Linux и Mac, поэтому я думал, что Java будет лучшим вариантом, поэтому я не хочу переключать язык, который я использую. Есть ли способ удалить все, что было сохранено в стеке после каждого рекурсивного вызова в Java? Вот мой код, на всякий случай, если есть ошибка.Java: Recursion вызывает ошибку переполнения стека, даже если код верен
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;
}
}
х и у точек генерируется из цикла, который проходит через изображение и проверяет, если точка была добавлена к форме, а если нет, как она делает форму от окружающего его пикселей.
UPDATE:
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 Heap Space, хотя я увеличил его до 2 Гб. Я добавляю каждый int [] [] в ArrayList, который, как я предполагаю, является проблемой. Как еще я могу хранить данные?
Это не дает прямого ответа на ваш вопрос, но; любая причина не просто использовать вложенный цикл, внешний для x и внутренний для y? Это было бы проще и эффективнее. (Вы также можете сделать одномерный индекс с одним циклом, каждый индекс - 'y * width + x'). – yshavit
У меня есть один в другом методе, и он смотрит на массив таблицы, и когда есть ячейка, которая возвращает true, она вызывает makeShape –
. Я бы предложил искать итеративный алгоритм флуда, чтобы избежать рекурсии. –