Использование заливки для подсчета приставных нулей в матрице

1

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

Правильный выход: 2 4

Токовый выход: 2 2 2

public class Test {
    public static void main(String[] args) {
        String[] in = getInput();
        char[][] map = getMap(Arrays.copyOfRange(in, 0, in.length));
        House h = new House(map);
        System.out.println(h);

    }

    private static String[] getInput() {
        String[] ret = {
                "11111",
                "10011",
                "11101",
                "10001",
                "11111"
            };
        return  ret;
    }

    private static char[][] getMap(String[] copyOfRange) {
        List<char[]> ret = new ArrayList<>();
        for (String x : copyOfRange) 
            ret.add(x.toCharArray());
        return  ret.toArray(new char[ret.size()][]);
    }

}

class House {
    private char[][] map;
    List<Integer> listOfAreas;
    House(char[][] map) {
        this.map = map;
        listOfAreas = getAreas();
    }


    private List<Integer> getAreas() {
        List<Integer> ret = new ArrayList<>();
        char[][] cMap = map.clone();
        for (int i = 0; i < cMap.length; i++) {
            for (int j = 0; j < cMap[i].length; j++) {
                if (cMap[i][j] == '0')
                    ret.add(countFlood(new Point(i,j),cMap));
            }
        }
        return ret;
    }

    private int countFlood(Point start, char[][] cMap) {
        int count = 0;
        Stack<Point> stack = new Stack<>();
        stack.push(start);
        while (!stack.isEmpty()) {
            Point p = stack.pop();
            if (cMap[p.getX()][p.getY()] == '0') {
                ++count;
                cMap[p.getX()][p.getY()] = '1';
                for (Point x : getAdj(p,cMap))
                    stack.push(x);

            }
        }
        return count;
    }

    private Point[] getAdj(Point p, char[][] cMap) {
        List<Point> ret = new ArrayList<Point>();
        if (p.getX() == 0)
            ret.add(new Point(p.getX() - 1, p.getY()));
        if (p.getX() != cMap.length - 1)
            ret.add(new Point(p.getX() + 1, p.getY()));
        if (p.getY() == 0)
            ret.add(new Point(p.getX(), p.getY() - 1));
        if (p.getY() != cMap[p.getX()].length - 1)
            ret.add(new Point(p.getX(), p.getY() + 1));

        return ret.toArray(new Point[ret.size()]);
    }


    public String toString() {
        StringBuilder ret = new StringBuilder();
        for (int x : listOfAreas)
            ret.append(x + " ");

        return ret.toString();
    }

}

class Point {
    private int x;
    private int y;
    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}
  • 0
    Вы должны просто отладить вашу программу. Узнайте, что происходит и где идет не так. Я бы начал с нескольких простых распечаток, чтобы увидеть ход программы и значения переменных в разных точках.
Теги:
algorithm
matrix
flood-fill

1 ответ

0
Лучший ответ

Проблема в коде getAdj: вы добавляете точки, которые идут вниз и влево, только когда соответствующая координата равна нулю; вы должны добавлять только тогда, когда оно не равно нулю:

private Point[] getAdj(Point p, char[][] cMap) {
    List<Point> ret = new ArrayList<Point>();
    if (p.getX() != 0) // <<== Use != instead of ==
        ret.add(new Point(p.getX() - 1, p.getY()));
    if (p.getX() != cMap.length - 1)
        ret.add(new Point(p.getX() + 1, p.getY()));
    if (p.getY() != 0) // <<== Use != instead of ==
        ret.add(new Point(p.getX(), p.getY() - 1));
    if (p.getY() != cMap[p.getX()].length - 1)
        ret.add(new Point(p.getX(), p.getY() + 1));

    return ret.toArray(new Point[ret.size()]);
}
  • 0
    Ничего себе, я пропустил это, купить, почему это не вызвало исключение arrayOutOfBounds? как только он вытолкнут в стек и оценен в if (cMap [p.getX ()] [p.getY ()] == '0')
  • 1
    @TristanMilan Вы правы, он потерпит крах, если любая из точек на границе будет установлена в '0' . Тем не менее, ваша карта имеет все '1' в верхней и левой границах, поэтому сбой никогда не произойдет.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню