Recursion 에서의 탈출 조건

항상 재귀호출을 할땐 탈출조건떔에 힘들더라구요 Recursive 한 사고방식이 잘 안되는 것 같습니다 ㅠㅠ
아래 코드에서의 탈출조건을 true,나 false로 잡았는데 첫번째로 들어온 함수녀석이 모든 재귀를 끝냈다면 Count를 리턴하도록 코드를 짜고 싶은데, 그렇게 짤려면 그 첫번째 함수에게만 특별한 변수를 주거나 다른 조건을 추가해 줘야 가능 할 것 같은데…

if(첫번째로 들어온 함수녀석이 모든 재귀를 마쳤다면){
return Count;
else{
return false;
}

이런식으로말이저

아니면 코드를 애초에 아래처럼 안짰어야 했던 걸까요? 조언 부탁드립니다!!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define N 8

typedef enum Check Check;
enum Check {

	CELL = 1, NO_CELL = 0, PREVIOUS = 2, NOW_CELL = 3,
};

int Cell[][N] = {
	{1,0,0,0,0,0,0,1},
	{0,1,1,0,0,1,0,0},
	{1,1,0,0,1,0,1,0},
	{0,0,0,0,0,1,0,0},
	{0,1,0,1,0,1,0,0},
	{0,1,0,1,0,1,0,0},
	{1,0,0,0,1,0,0,1},
	{0,1,1,0,0,1,1,1}
};

int Cell_Count(int x, int y);

int main() {

	printf("%d\n", Cell_Count(1, 1));

	return 0;
 }

int Cell_Count(int x, int y) {

	static int Count = 0;

	if (Cell[x][y] == CELL && Cell[x][y] != NOW_CELL)
		Count++;

	printf("Count : %d\n", Count);
	Cell[x][y] = NOW_CELL;

	if (Cell[x][y] == NOW_CELL) {
		if ((x + 1 <= N) && (Cell[x + 1][y] != NO_CELL) && (Cell[x + 1][y] != NOW_CELL)) {
			if (Cell_Count(x + 1, y))
			return true;
		}
		if ((y + 1 <= N) && (Cell[x][y + 1] != NO_CELL) && (Cell[x][y + 1] != NOW_CELL)) {
			if (Cell_Count(x, y + 1))
			return true;
		}
		if ((x - 1 >= 0) && (Cell[x - 1][y] != NO_CELL) && (Cell[x - 1][y] != NOW_CELL)) {
			if (Cell_Count(x - 1, y))
			return true;
		}
		if ((y - 1 >= 0) && (Cell[x][y - 1] != NO_CELL) && (Cell[x][y - 1] != NOW_CELL)) {
			if (Cell_Count(x, y - 1))
			return true;
		}
		if ((x + 1 <= N) && (y + 1 <= N) && (Cell[x + 1][y + 1] != NO_CELL) && (Cell[x + 1][y + 1] != NOW_CELL)) {
			if (Cell_Count(x + 1, y + 1))
			return true;
		}
		if ((x - 1 >= 0) && (y - 1 >= 0) && (Cell[x - 1][y - 1] != NO_CELL) && (Cell[x - 1][y - 1] != NOW_CELL)) {
			if (Cell_Count(x - 1, y - 1))
			return true;
		}
		if ((x + 1 >= N) && (y - 1 >= 0) && (Cell[x + 1][y - 1] != NO_CELL) && (Cell[x + 1][y - 1] != NOW_CELL)) {
			if (Cell_Count(x + 1, y - 1))
			return true;
		}
		if ((x - 1 >= 0) && (y + 1 <= N) && (Cell[x - 1][y + 1] != NO_CELL) && (Cell[x - 1][y + 1] != NOW_CELL)) {
			if (Cell_Count(x - 1, y + 1))
			return true;
		}
	}
	return false;
}

ㅋㅋㅋㅋㅋ

저는 징징대며 쓰는 글은 쳐다보기도 싫어서 쩝.
질문하는 요령 좀 부족하시네요. 암튼 열심히 공부하시는건 보기 좋습니다.

1 Like

질문이 대략 재귀를 중도 탈출하고 싶으시다는 것 같은데, 재귀의 기본 구조는 그렇게 구현하기 쉽지 않죠.
그럴 때 쓸 수 있는건 setjmp, longjmp 예요.
setjmp.h 에 들어있죠.

이란 말이 모호하니 아마 모호하게 작성중이실겁니다.

우선 답변 감사드립니다! 항상 글을 못쓴다는 이야기를 많이 들어와서 글을 작성할떄는 몇번씩 검토하면서 연애편지 쓰듯이 신중하게 했었는데…ㅠㅠ 글을 쓰는건 참 많이 어려운 것 같네요… 자주 질문하면 더 좋아지겠죠?ㅋㅋㅋ 말씀하신것 처럼 재귀적인 구조를 구현하는게 많이 어려운 것 같습니다 조언해 주신 setjmp키워드로 검색해보니 유용 할 것 같지만 코드가 많이 부자연 스러워지는 단점도 있는 것 같네요. 깔끔하게 재귀적인 구조로 작성하려면 많이 연습이 필요할 것 같네요ㅠ

맞습니다 코드가 조금 부자연스러워지죠.
대신 꼬리재귀( tail recursion ) 형태로 최적화되지 않고 return 에 return 에 return 을 해야 되는 경우,
성능이 보상해주죠.

그리고 찬찬히 들여다보기 귀찮아서 정확히 이 코드가 무슨 일을 의도하는지는 잘 모르겠으나,
flood fill 유사한 함수인것 같군요. 참고하시고,
맵을 하나 더 만들고 탐색중인 경로를 마킹하는 식의 방법으로 효율성을 높일 수도 있을겁니다.

조언감사드립니다!