인프런 커뮤니티 질문&답변

버럼님의 프로필 이미지
버럼

작성한 질문수

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

바닥 장식 (백준 1388)

answer++ 위치 질문

해결된 질문

작성

·

174

1

// 1. dfs 실행
		int answer = 0;
		for(int i = 1; i <= N; i++) {
			for(int j = 1; j <= M; j++) {
				if(visited[i][j] == false)
					dfs(i, j);
					answer++;
			}
		}

안녕하세요.

dfs문을 호출한 이후에 answer++;를 했을 때는, 주어진 값과 다르게 나오는데, 어떤 부분에서 차이가 있는지 궁금합니다.. 감사합니다!

답변 1

1

버럼님 안녕하세요!

위에서 문제가 발생하는 이유는 if문에 해당하는 중괄호를 사용하지 않았기 때문입니다! 아래 두 가지 코드를 비교해보면서 설명 해볼게요!

// 1안
// 1. dfs 실행
int answer = 0;
for(int i = 1; i <= N; i++) {
    for(int j = 1; j <= M; j++) {
        if(visited[i][j] == false)
	    dfs(i, j);
	    answer++;
    }
}

// 2안
// 1. dfs 실행
int answer = 0;
for(int i = 1; i <= N; i++) {
    for(int j = 1; j <= M; j++) {
        if(visited[i][j] == false){
	    dfs(i, j);
	    answer++;
        }
    }
}

 

겉보기에 1안과 2안은 매우 유사하지만 완전히 다른 동작을 합니다. 1안은 버럼님이 작성하신 코드이고, 2안은 버럼님이 의도하셨던 코드 일텐데, 그 차이는 "if문의 조건에 따라 수행되는 코드의 범위"에 있습니다. 1안 같은 경우에는 if문에 중괄호를 생략했고, 이런 경우 바로 다음 코드 한 줄만 if문에 종속됩니다. 그러므로 의도했던 대로 "visited[i][j] == false 인 경우 dfs를 1회 수행하고 answer를 증가 시킨다"라고 수행되는 것이 아니고 "visited[i][j] == false 인 경우 dfs를 1회 수행한다"라고 수행되는 거죠. 그런 뒤에 answer++은 아무런 조건 없이 매 반복문마다 수행이 되기 때문에 1안에 종료된 다음에 answer는 항상 N*M의 값을 갖고 있게 될 것입니다.

일종의 눈속임처럼 줄 바꿈/띄어쓰기 때문에 같은 조건문에 묶일 것 같지만, 실제로는 1안과 아래 코드가 동일한 겁니다.

// 3안 (== 1안)
// 1. dfs 실행
int answer = 0;
for(int i = 1; i <= N; i++) {
    for(int j = 1; j <= M; j++) {
        if(visited[i][j] == false) dfs(i, j);
	answer++;
    }
}

 

그에 비해 2안은 중괄호를 명확하게 사용했기 때문에 우리가 원하는 조건이 발생하면 dfs와 answer를 모두 수행하게 됩니다.

 

그래서 정리를 하자면, 중괄호를 되도록 생략하지 않는 것이 무조건 안전합니다! 코딩이 손에 좀 익고, 코딩 테스트에서는 시간을 아끼기 위해서 혹은 코드를 간결하게 짜기 위해서 생략하는 경우도 있지만, 큰 차이가 나지 않기도 하고 한번 실수하면 찾아내기 정말 어려운 버그이기도 합니다. 그러니 앞으로는 모든 반복문, 조건문에 중괄호를 사용하시는 걸 추천 드립니다! :)

또 궁금한 점 있으면 알려주세요! 오늘도 공부 화이팅입니다 :)

버럼님의 프로필 이미지
버럼

작성한 질문수

질문하기