-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
1주차 과제 풀이 제출 #9
base: main
Are you sure you want to change the base?
1주차 과제 풀이 제출 #9
Conversation
재귀적인 사고를 연습하는 단계라서 우리가 흔하게 반복문으로 푸는 문제를 재귀적인 방법으로 바라보는 연습을 한 것으로 생각하시면 될 것 같습니다.
일반적인 재귀 함수에서는 함수 호출 스택에 값을 저장하고 있고, 꼬리 재귀 같은 경우에는 파라미터로 값을 계속해서 전달하여 값과 목을 하위 함수로 전달합니다. |
재귀를 사용하는 것이 더 느릴 수 밖에 없습니다. 추가적인 메모리를 할당하고 해제하기 때문에요. 그래서 우리가 재귀적인 사고로 문제를 해결 -> 꼬리 재귀로 변경 -> 꼬리 재귀 최적화로 재귀를 제거 하는 순서로 문제를 풀어야 합니다. |
public int solution2_1(int[] input) { | ||
if (input.length == 0) { | ||
return 0; | ||
} | ||
if (input.length == 1) { | ||
return input[0]; | ||
} | ||
int mid = input.length / 2; | ||
return solution2_1(Arrays.copyOfRange(input, 0, mid)) + solution2_1(Arrays.copyOfRange(input, mid, input.length)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2개씩 나누면서 1개가 될 때까지 나누어서 더하는 방식이군요 ㅎㅎ 저는 생각 못 했던 방식이네요!
private int plus_1(int input, int output) { | ||
if (input == 0 || input == 1) { | ||
return input; | ||
} | ||
return output + plus_1(input - 1, output) + plus_1(input - 2, output); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
output이 처음에 0으로 주어지고, 재귀적인 호출에도 같은 output을 계속 넘겨주기 때문에 0에서 변하지 않네요. 그래서 위에서 구현했던 solution2
랑 같은 결과가 나오게 되겠어요. 따라서 output은 없어도 되겠네요
private int plus_2(int input, int output) { | ||
while(true) { | ||
if (input == 0 || input == 1) { | ||
return input; | ||
} | ||
return output + plus_2(input - 1, output) + plus_2(input - 2, output); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아마 꼬리재귀 최적화를 시도하셨던 것 같네요. 꼬리 재귀 최적화가 된 결과는 solution1과 동일하긴 해요. 그전에 꼬리재귀 최적화가 된 모양은 다음과 같습니다.
public int _solution(int input, int count, int a, int b) {
if (input == 0 || input == 1) {
return input;
}
if (input == count - 1) {
return b;
}
return solution(input, count + 1, b, a + b);
}
public int solution(int input) {
return _solution(input, 0, 0, 1);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hannut91
안녕하세요. 코드숨 공개 레포로 개인공부하고 있는 개발자입니다~ 먼저 좋은 학습자료 올려주셔서 감사하다는 인사의 말씀 드립니다.
저는 자바로 공부하고 있는데 꼬리 재귀 최적화는 현재 자바에서 지원되지 않습니다.
https://blogs.oracle.com/javamagazine/post/curly-braces-java-recursion-tail-call-optimization
I spoke to Brian Goetz, the Java language architect at Oracle, about TCO back in 2014. At the time, he told me that it’s on a list of things to be added to the JVM. I caught up with him recently (이게 블로그 글로 미루어보아 2022년인거 같습니다) to discuss the topic, and he said that while progress has been made, and more may occur in the future, TCO hasn’t been fully implemented due to some security concerns.
아래 링크를 확인해보시면 workaround가 있는 것 같긴합니다.
https://stackoverflow.com/a/53787951
https://github.com/jonckvanderkogel/java-tail-recursion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kyupid 맞습니다. 꼬리 재귀 최적화가 된 결과가 아니라 꼬리 재귀로 작성된
이라고 정정해야겠네요! 제보 감사합니다 ㅎㅎ
자바에서 꼬리 재귀 최적화를 지원하지 않으므로, 직접 꼬리 재귀 최적화를 해야 합니다.
소감
풀이 설명 및 궁금증
1번 문제
2번 문제
3, 4번 문제
5번
6번