Skip to content

Conversation

@yumi530
Copy link

@yumi530 yumi530 commented Jan 14, 2024

1주차 과제 1~4번 제출합니다 !
꼬리 재귀는 어려웠던 것 같습니다 .. !

@hannut91
Copy link
Contributor

꼬리 재귀로 바꾸는게 어려우셨군요. 꼬리 재귀의 특징을 떠올려 보시면 조금 도움이 됩니다.

꼬리재귀는 함수 마지막 줄에 어떠한 추가적인 연산도 없고 함수 호출로만 끝나야 합니다. 그렇다면

return solution2(nums2);

되어야겠죠.

근데 이러면 꼬리 재귀가 되었지만, 우리가 원하는 값이 없잖아요. 첫 번째 요소부터 전부 더해야 되는데 더해질 변수가 존재하지 않죠. 그래서 이러한 변수를 만들어야 돼요.

solution2(nums2, 0);

public int solution2(int[] nums, int acc) {
    if(nums.length == 0) {
        return 0;
    }
    
    int[] nums2 = Arrays.copyOfRange(nums, 1, nums.length);
    return solution2(nums2, acc + nums[0]);
}

그래서 꼬리재귀의 특징은 파라미터에 뭔가 덕지덕지 붙는다는거예요. 뭔가 기억할 값을 스택에 저장할 수 없으니 파라미터로 계속 전달해 주어야 되는거죠.

꼬리 재귀로 만들었다면 꼬리 재귀 최적화는 사실 엄청 쉬워요. 꼬리 재귀 최적화는 컴파일러가 대신 해줄 수 있을정도로 기계적으로 수행할 수 있어요.

재귀 호출로 파라미터의 값을 변경하고 있었는데, 더 이상 함수 호출을 할 수 없으니가 값 대입으로 변경해 주어야 해요. 그래서 파라미터 int acc가 사라지죠. 그리고 새로운 함수 호출하는 대신 값을 변경하기만 하면 됩니다.

solution2(nums2);

public int solution2(int[] nums) {
    int acc = 0;
    int[] nums2 = Arrays.copyOfRange(nums, 0, nums.length)

    while(true) {
        if(nums.length == 0) {
            return acc;
        }

        acc = acc + nums2[0];
        int[] nums2 = Arrays.copyOfRange(nums, 1, nums.length);
    }
}

물론 위의 코드에서 Array모두를 복사하는 것은 낭비일 수 있으니 이것도 최적화를 할 수 있겠죠

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants