inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[자바/Java] 문과생도 이해하는 DFS 알고리즘! - 입문편

바이러스 (백준 2606)

인덱스설정문의

해결된 질문

306

zergcity

작성한 질문수 24

1

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        M = Integer.parseInt(br.readLine());
        graph = new boolean[N][N];
        visited = new boolean[N];
        int x, y;
        for (int i=0; i<=M; i++) {
            StringTokenizer tokenizer = new StringTokenizer(br.readLine());
            x = Integer.parseInt(tokenizer.nextToken())-1;
            y = Integer.parseInt(tokenizer.nextToken())-1;
            graph[x][y] = true;
            graph[y][x] = true;
        }
        dfs(0);
        System.out.println(answer - 1);
        br.close();
    }

    void dfs(int index) {
        visited[index] = true;
        IntStream.range(0, M).forEach(i -> {
            if (!visited[i] && graph[index][i]) dfs(i);
        });
        answer++;
    }

위에처럼 저는 +1을하지않고(그래프에 0인덱스들은 사용을 안한다고 생각해서요.)
대신 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수를 입력받을 때 -1을해줘서 처리했는데요.

예제입력은 정상처리 되나 실제 제출해보면 런타임 에러 (ArrayIndexOutOfBounds)가 발생합니다. +1을 해줘야하는거같은데... 제가 생각한 배열사이즈, -1로 입력받기가 잘못된걸까요?

java 코딩-테스트 알고리즘 dfs

답변 1

2

개발자로 취직하기

zergcity님 안녕하세요 :)

작성하신 대로 하나 감소하는 것은 문제가 되지 않습니다! 제대로 동작하지 않는 이유는 크게 2가지가 있어요.

  1. IntStream의 Range 버그

IntStream.range(0, M).forEach(i -> {
    if (!visited[i] && graph[index][i]) dfs(i);
});
  • 위에서 작성하신 코드는 0부터 M까지 반복하도록 되어있습니다.

  • 그런데 실제 우리가 의도한 동작은 0부터 N까지 돌기를 원하는 거고, M은 간선의 개수이기 때문에 ArrayIndexOutOfBounds 런타임 에러가 발생하고 있습니다.

  • 예를 들어 컴퓨터의 수는 3개라서 N = 3인데, 간선의 개수가 4개라면 위 IntStream에서 visited와 graph의 범위를 벗어나기 때문에 문제가 발생할 겁니다.

  • 이걸 고쳐도 불량이 하나 더 있어요!

 

  1. 간선 입력 시 버그

 for (int i=0; i<=M; i++) {
    StringTokenizer tokenizer = new StringTokenizer(br.readLine());
    x = Integer.parseInt(tokenizer.nextToken())-1;
    y = Integer.parseInt(tokenizer.nextToken())-1;
    graph[x][y] = true;
    graph[y][x] = true;
}
  • 위에 작성하신 코드에서 M개의 간선 정보를 입력 받으려면 i <= M 이 아니라 i < M까지 돌아야 합니다.

  • 위 코드는 M+1개의 간선을 기다리기 때문에 기대한대로 동작하지 못할 거니 주의가 필요해 보여요!

 

만약 단순 실수로 위 버그들이 발생한 거라면 변수명을 조금 더 명시적으로 작성해서 헷갈리지 않게 하는 게 좋을 것 같아요. M 대신 edgeCount를 사용했다면 첫 번째 버그가 발생할 확률이 조금 낮아질 것 같아요.

그리고 ArrayIndexOutOfBounds 에러가 발생했다는 건 결국 배열 접근 시 의도치 않게 큰 인덱스로 접근하는 것이 직접적인 원인이기 때문에, "배열 접근 중에 뭘 잘못하고 있지?"라는 식으로 접근해 보면 조금 더 빨리 디버깅 하고 코딩 테스트 중에도 빠르게 고칠 수 있을 것 같습니다!

혹시 더 필요하신 내용 있으면 알려주세요 :D

dfs 부문을 이렇게 작성해도 되나요?

1

74

1

x랑 y를 거꾸로 쓰는 개념이 너무 헷갈립니다...

1

97

2

dfs 파라미터에 count를 넣는이유

1

65

2

graph 채울때 for문 설계 질문

1

73

2

질문있습니다.

1

75

1

다른 강의 언제나오나용?

1

94

2

노드간 거리 계산

1

146

1

안녕하세요, 혹시 다른문제도 여쭤볼 수 있을까요?

1

131

1

최근에 올린 질문, 코드블럭으로 공유드립니다!

1

143

1

질문이 있습니다. dfs 메서드에 order를 이렇게 구현하면 안되는 이유가 무엇인가요?

0

135

2

깊이우선탐색2 백준 24480 수업노트에...

1

120

1

백준 24479 문제 제출 결과 "틀렸습니다" 라고만 나와서 어떤 부분이 틀렸는지 잘 모르겠어요 피드백 부탁드립니다

1

251

3

graph 만들때 boolean[][] 으로 만드는 경우랑 int[][] 나 ArrayList<Integer>[] 로 만드는 기준이 어떻게 되나요?

1

202

2

graph를 2차원 배열 또는 List로 하는 기준을 어떤식으로 잡으면 좋을까요...?

1

224

1

강사님 안녕하세요! 깊이 우선 탐색 2 (백준 24480)에서 제공하는 풀이 코드에서 궁금한 점이 있어서 질문 드립니다!

1

328

3

촌수 계산

1

355

3

연결 요소의 개수 (백준 11724)

1

268

1

백준 24479 문제 시간 초과 질문 드려요

1

384

1

백준 실행시 틀립니다.

1

373

1

재귀대신 스택으로 구현하면 안될까요?

1

410

1

dfs 매개변수에서 y,x 를 왜 순서를 반대로 쓰셨는지 궁금합니다.

1

373

1

안녕하세요 11724번 질문드려요!

2

316

1

출력할 때 BufferedWriter? StringBuilder?

1

513

1

answer++ 위치 질문

1

257

1