티스토리 뷰
안녕하세요.
오늘은 조금 이론적인 이야기를 해볼까 합니다.
2023.08.18 - [iOS개발/프로그래머스 연습] - 프로그래머스 이모티콘 할인행사 (Lv.2) 문제 풀이
이전에 풀었던 문제에 나왔던 부분인
순열에 관해 이야기 할까 합니다.
* 순열
- 서로 다른 원소들(n개) 중에서 몇개(r개)를 중복없이 순서에 상관있게 나열하는 것을 의미합니다.
이걸 코드로 작성한다고 합시다. 아래처럼 카드들을 미리 만들어 둡시다.
let cards = ["A","B","C","D"]
만약 한개라면 그냥 저 상태 그대로 출력하는게 맞겠죠?
예를 들면 아래처럼요 (함수 전체는 나중에 보여드릴께요)
if(level == 1){ // 1개 뽑기라면
var results : [[String]] = []
for i in cards{
results.append([i])
}
return results // 결과 [["A"], ["B"], ["C"], ["D"]]
}
그럼 이제 2개를 뽑을때로 넘어가 봅시다.
중복되는거는 사용하면 안된다고 했죠?
그럼 어떻게 나열해야 할까요?
그림으로 보면 아래 처럼 표현 할 수 있어요
그럼 기존에 만든 배열 앞에 카드를 하나 넣어준다고 생각하면
이미 사용한 카드이면 패스하고 없는 카드이면 넣어서 배열을 만들면 되지 않을까요?
아래처럼요
var results : [[String]] = []
for i in cards {
for lastArr in [["A"], ["B"], ["C"], ["D"]] {// 1개짜리 배열(이전 단계 결과값)
if(!lastArr.contains(i)){ // 이전에 사용된 카드는 사용X
var newElement = lastArr
newElement.append(i)
results.append(newElement)
}
}
}
print(results)
// 실제 출력 값
// [["B", "A"], ["C", "A"], ["D", "A"], ["A", "B"], ["C", "B"], ["D", "B"], ["A", "C"], ["B", "C"], ["D", "C"], ["A", "D"], ["B", "D"], ["C", "D"]]
근데 저희가 항상 이걸 매번 수동으로 r개 뽑을때마다 계속 함수를 새로 만드는건 힘들겠죠?
r 개를 뽑으면 비슷한 구조의 함수를 r번 반복 => 이럴때는 재귀함수 만큼 좋은게 없죠
* 재귀함수
- 함수 안에 자기자신을 재참조하는 식으로 재정의한 함수
- 쉽게 말하면 함수안에 함수(그것도 본인)가 있는 구조라 생각하시면 됩니다.
단 r = 1 인 1개 뽑기일 때 바로 저희가 아는 값이 나오는 편이 좋겠죠?
또 재귀인 만큼 지금 만든 배열이 몇자리(level)이고 저희의 목표 자릿수(r)를 알아야겠죠?
(level 은 쉽게 생각하면 진행 상황을 의미한다고 생각하면 됩니다.)
즉 저희가 함수를 처음 이용할때는 level 과 r을 동일한 값을 넣어주지만
실제 반복를 돌리기 위해 둘로 나누어 넣는다고 생각하시면 됩니다.
(r은 count 로 바꾸어서 넣겠습니다 - 헷갈림 방지)
# 순열 코드 (swift)
let cards = ["A","B","C","D"]
func permutation(count : Int, level : Int) -> [[String]] {
if(level == 1){
var results : [[String]] = []
for i in cards{
results.append([i])
}
return results
}else{
var results : [[String]] = []
for i in cards {
for lastArr in permutation(count: count, level: level-1) { // 이전 값 가져오기
if(!lastArr.contains(i)){
var newElement = lastArr
newElement.append(i)
results.append(newElement)
}
}
}
return results
}
}
이러면 정상적으로 배열이 나오는걸 확인할 수 있습니다.
* 그럼 중복 순열은 어떻게 하나요?
- 저기 중복을 방지하기위해 넣은 조건문만 제거하면 바로 가능합니다.
# 중복 순열 코드 (swift)
func permutation(count : Int, level : Int) -> [[String]] {
if(level == 1){
var results : [[String]] = []
for i in cards{
results.append([i])
}
return results
}else{
var results : [[String]] = []
for i in cards {
for lastArr in permutation(count: count, level: level-1) {
//if(!lastArr.contains(i)){ 비교문 제거
var newElement = lastArr
newElement.append(i)
results.append(newElement)
//}
}
}
return results
}
}
간단하죠?
재귀함수의 경우 처음부터 너무 어렵게 생각하는 것보다는
단순하게 생각하는 편이 확실히 편한 것 같네요.
공부하시는 분들에게 조금이나마 도움이 되었으면 좋겠네요.
오늘도 파이팅입니다.
'iOS개발 > 프로그래머스 연습' 카테고리의 다른 글
프로그래머스 개인정보 수집 유효기간 (Lv.1) 문제풀이 (0) | 2023.09.18 |
---|---|
프로그래머스 이모티콘 할인행사 (Lv.2) 문제 풀이 (0) | 2023.08.18 |
프로그래머스 성격유형검사(Lv. 1) 문제풀이 (0) | 2023.08.11 |