2015-12-17 3 views
0

Я пытаюсь создать программу, которая проходит через изображение спрайта, а затем делает каждую фигуру в ней новым изображением. Например, если мы взяли Марио, я хочу, чтобы шляпа была одним изображением, лицо было другим, и так далее. Я получил свою программу для работы с небольшими изображениями 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, который, как я предполагаю, является проблемой. Как еще я могу хранить данные?

+0

Это не дает прямого ответа на ваш вопрос, но; любая причина не просто использовать вложенный цикл, внешний для x и внутренний для y? Это было бы проще и эффективнее. (Вы также можете сделать одномерный индекс с одним циклом, каждый индекс - 'y * width + x'). – yshavit

+0

У меня есть один в другом методе, и он смотрит на массив таблицы, и когда есть ячейка, которая возвращает true, она вызывает makeShape –

+1

. Я бы предложил искать итеративный алгоритм флуда, чтобы избежать рекурсии. –

ответ

1

Java хорошо известен своей автоматической и четко определенной системой управления памятью - как правило, не рекомендуется управлять собственной памятью, даже если это возможно (потому что на каком-то уровне она на самом деле).

Что даст вам очищающий стек, если время выполнения альгоритма позволит вам получить бороду и рассказать истории об этом своим великим детям?

Не делайте это рекурсивным - подумайте о некоторой итеративной форме алгоритма. Например, вы можете перебрать пикселей всего изображения и добавить их к соответствующему изображению (из-за его цвет), который будет храниться в некотором HashMap, как в этом псевдокоде

HashMap<Color, Image> images= new HashMap<Color, Image>(); 

    for(Pixel pixel : originImage) 
     Color color = pixel.getColor(); 
     images.get(color).put(pixel) 

Не тратьте свою жизнь плохо код

+0

Если бы я сделал это, как бы я хотел отделить пиксели от тех, которые касаются , поэтому я могу иметь все формы цвета на отдельных слоях, а не каждый слой, содержащий все формы данного цвета. –

+1

, конечно, - это всего лишь простой пример - прочитать о [Flood fill alghoritm] (https://en.wikipedia.org/wiki/Flood_fill) или alghoritm Смита (а не текст Смит-Уотермана) - я реализовал это где-то и было хорошо, но трудно найти реализацию. –

+0

Я придумал что-то, основанное на Wiki, но теперь у меня заканчивается куча пространства. –

Смежные вопросы