설계 조건
- 적어도 하나의 Base Case가 존재해야 함. ( 종료되는 case )
- 모든 case는 결국 Base Case로 수렴함.
Recursion과 반복문 작성시 주목할 차이점
- 암시적 (implicit) 매개변수을 명시적 (explicit) 매개변수로 바꾸어라
예시 (1) 순차 탐색 [ Sequention Search ]
int search(int []data, int target){
for(int i=0; i < data.length; i++){
if(data[i] == target) return i;
}
return -1;
}
- 말 그대로 순차적으로 탐색하는 알고리즘으로 찾는 데이터가 어디에 위치하는지 index 번호 리턴하는 경우
- 만약 데이터가 정렬되어 있다면 이진검색 진행
- 만약 순차 검색을 위와 같이 설계한다면
검색 구간은 index[0] ~ index[n - 1] 구간을 검색하는 것임. 이때 n-1은 명시적으로 표현되어 있으나, index[0]은 묵시적으로 시작 값이라는 것을 알기에 이는 암시적 매개변수임. - 즉, 시작지점이 따로 명시되어 있지 않고 0부터 순환할 경우 이는 '암시적 매개변수'라고 볼 수 있음.
- 일반적으로 Recursion으로 사용하지 않는 경우에 위와 같이 사용함. 하지만 Recursion으로 프로그래밍을 할 때에는 명시화 함.
매개변수의 명시화 : 순차 탐색
private int search(int []data, int begin, int end, int target){
if (begin > end) return -1;
else if( data[begin] == target ){
return begin;
} else {
return search(data, begin++, end, target);
}
}
- Recursion
원래 배열 데이터와 상관 없이 시작 값과 끝 값 사이에 값이 존재하는지 확인하는 것 - 기존 코드와 차이는 시작 값과 끝 값을 명시적으로 표현함.
- 이는 Recursion으로 작성할 때 염두해야하는 가장 기본적인 원칙임.
- 다시 자기 자신을 호출하며 시작 값은 변경됨.
고로 일반적으로 Recursion으로 선언된 함수들은 매개변수들은 맨 처음 외부에서 호출 될 때의 상황만 생각하고 설계해서는 안 됨.
무한루프에 빠질 수 있기 때문임.
순차 탐색 : 다른 버전
private int search(int []data, int begin, int end, target){
if(begin > end) return -1;
else if ( data[end] == target ) return end;
else {
return search(data, begin, end--, target);
}
}
- begin 부터가 아닌 end부터 -1을 하며 begin까지 값을 탐색하는 것
매개변수의 명시화 : 최대값 찾기
private int searchMax(int []data, int begin, int end){
// begin이 마지막 번호까지 왔을 경우 배열의 마지막 데이터 반환
if (begin == end) return data[begin];
else {
return Math.max(data[begin], searchMax(data, begin++, end));
}
}
- begin과 end 사이의 최대값을 찾음
- 이는 첫 번째 중에 제외한 최대값과 범위의 최대값과 비교해 가장 큰 값을 찾는 것임
매개변수의 명시화 : Binary Search
private int binarySearch(String []items, String target,
int begin, int end){
// begin은 메서드가 실행하면 하나씩 증가함
// 만약 증가하다 end보다 커질 경우 -1을 반환함
if (begin > end) return -1;
else{
// 이진탐색법은 가운데 값을 기준으로 진행함
int mid = (begin + end) / 2;
/*
compareTo는 비교하는 문자열과 각각의 자리를 비교해
비교 값에서 매개변수의 값을 뺄셈하여 차이를 int형으로 반환함
tmpStr.compareTo(str); 메소드
만약 tmpStr이 str과 같으면 0,
만약 tmpStr이 str 보다 크면 1,
만약 tmpStr이 str 보다 작으면 -1
*/
if ( items[mid].compareTo(target) == 0 ) return mid;
else if ( items[mid].compareTo(target) > 0)
return binarySearch(items, target, mid+1, end);
else {
// items[mid].compareTo(target) < 0
// 즉, items[mid]의 값이 target 보다 작을 경우
return binarySearch(items, target, begin, mid-1);
}
}
}
참고. Binary search는 정렬된 데이터에 적용 가능
'Programming > Algorithm' 카테고리의 다른 글
알고리즘: 재귀함수(5) 예제 N Queens (0) | 2021.03.23 |
---|---|
알고리즘: 재귀함수(4) 예제 Counting cells in a Blob (0) | 2021.03.23 |
알고리즘: 너비 우선 탐색 (Breadth First Search) (0) | 2021.03.16 |
알고리즘: 재귀함수 (3) 응용: 미로찾기 (0) | 2021.03.16 |
알고리즘: 재귀함수 (1) Recursion (0) | 2021.03.14 |