[CodeStatesLog] Recursion in Java

hk·2022년 5월 24일
0

CodeStatesLog

목록 보기
4/15

[Week05][TUE 24 MAY 2022] 자바 재귀 연습문제 페어프로그래밍

몇가지 배운 점, 느낀 점 기록.


재귀는 간단해보이지만 그래서 더 어색하다

자꾸 sum += num; 이런 거 쓰고 싶은 거 어떡하냐..

합을 구하는 문제에서
sum = sum + num;
이렇게 재귀 안 써서 풀고 오류나고..

difficult() 라는 재귀 함수를 쓴다면... 😥

public int difficult(int num){
return difficult(num-1) 연산어쩌구 num;
}

반복하고 싶은 부분에 재귀함수를 쓰면 되는구나~

내가 이해한 게 맞는지 잘 모르겠는데
페어님께 설명하면서 이해한 부분도 있고
오후에 라이브세션 때 설명 들으면 더 잘 이해가 가겠지


isOdd 홀수 여부 리턴하기

이거 반복문에서도 풀었는데

그때 내가 풀었던 방식은
양수일 때는 -2를 하고 음수일 때는 +2을 해서
+1일 때는 true 리턴, 0일 때는 false를 리턴
양수랑 음수로 if문을 나눠서 사용했다.
그런데 이렇게 하면 +1, -1, 0을 다 따로 리턴해줘야하는 문제가 있어서
내 코드는 정말 길었다. ㅋㅋ....
(근데 레퍼런스도 안 찾아봤음 )

오늘도 그렇게 풀려니까 이건 좀 아닌 것 같다..
레퍼런스 참고 ㄱㄱ
(페어할 땐 다 지우고 풀었음!!)

진짜 신박하고 간단한 방법
음수를 양수로 바꿔주면 되는 것이었다 !!!

음수->양수로 바꿈
양수 모두 -2를 계속 해줌
0은 return false
1은 return true

딱 4줄이면 끝나
사람이 이래서 배워야 하는구나


head와 tail은 이런 것일까?

head로 제일 앞을 받고(?) tail로 나머지 배열을 받은 다음
tail 안의 tail 안의 tail 반복..

그러니까 대충

int[] head = 어쩌구
int[] tail = 나머지 어쩌구
head + 재귀함수명(tail)

이것이 반복되는 문제들이 대부분이었다

쉽게 생각해야했다.. 그렇지만 나는 또 잡고 늘어져보았다

take(num,arr) 문제에서 take로 정의한 재귀함수는
arr이란 배열에서 맨앞에서부터 num개의 요소를 배열로 리턴.

예를 들어
arr = {30, 40, 50, 60} 이라면

take (3,arr) = take (3, {30, 40, 50, 60} ) = ?
head = {30}
tail = take(2, {40, 50, 60})

take (2, {40,50,60})
head = {40}
tail = take(1,{50,60})

take(1, {50,60})
head = {50}
tail(0, {50}) = 없음

이걸 반복하는 것이라고 이해했다.
내가 이해한 게 맞는지 확신이 없어 ㅠ
페어님도 이게 맞는 것 같다고 하셨으니까 일단 넘어감


Arrays.copyOfRange()

필요한 head나 tail을 복사할 때 사용했다.

int[] head = Arrays.copyOfRange(arr, 0, 3);

head라는 새로운 배열은
arr이라는 배열의 0번째 인덱스에서
3번째 인덱스 앞까지 복사를 해준 것이라는 뜻

예를 들어

arr = {10, 20, 30, 40, 50}
int[] head = Arrays.copyOfRange(arr, 0, 3);
head = {10, 20, 30} 

int[] 새로운배열명 = Arrays.copyOfRange(원본, 시작인덱스, 카피가 끝나는 인덱스 + 1)

헷갈린다
근데 더 헷갈리는 건 바로 다음에 찾아옴


System.arraycopy()

배열을 합쳐주기 위해서 System.arraycopy()을 썼는데...

System.arraycopy(복사하려는원본, 원본시작인덱스,복사출력대상,복사해와서어느부분부터쓸것인지,원본에서복사본까지어느만큼읽어서쓸것인지)

설명하려니까 진짜 대박 너무 길어
그래도 풀어서 써보니까 이해가 좀 된다네요~~

int arr1 = new int[]{10,20,30,40,50};
int arr2 = new int[3];
System.arraycopy(arr1, 1, arr2, 0, 3);
// -> 결과 {20,30,40}

그려


reverseArr

모든 건 12번을 위한 빌드업이었다😭

12번 어떻게 접근해야할지 레퍼런스를 봐도 이해가 안 가서..
하지만 테스트는 통과했으니까 이해한 걸 써보자면

{1,2,3,4,5} 이것이 원본 배열이라면
거꾸로 만들기 위해서 아래와 같은 연산을 반복해야한다

{5,1,2,3,4} head [0] + tail[1-4]
{5,4,1,2,3} [0] + head [1] + tail[2-4]
{5,4,3,1,2} [0] + [1] head [2] + tail [3-4]
{5,4,3,2,1} [0-2] +[3] tail [4]
이렇게 head + tail로 나누어서
tail로 받은 남은 배열을 계속 반복해서 계산

reverseArr(대충 tail을 카피하는 코드)
여기서 카피는 위에서 쓴 Arrays.copyOfRange()를 썼고
카피한 걸로 새로운 배열 만들어주는 건
또 위에서 쓴 System.arraycopy()를 썼다.

list.reverse() 그립다
잘 지내니.. 내 목소리 들리니.. 🐍🐍🐍


Stream으로 concat() 쓰기

head와 tail 합치는 건
처음에 생각했던 건 concat인데
import java.util.stream.IntStream;
이게 없어서인지 안 되더라
이거 입력해주면 stream으로도 쓸 수 있음

int[] output = IntStream.concat(IntStream.of(head), IntStream.of(tail)).toArray();
return output;

코플릿 풀 때 코드 시작부분에

import java.util.*; 

이게 있으니까

import java.util.stream.IntStream;

이것도 포함되는 줄 알았는데 아닌가봐


논리합, 논리곱

논리합 = OR 연산, 둘 중 하나라도 참이면 결과는 참이다
논리곱 = AND 연산, 둘 중 하나라도 거짓이면 결과는 거짓이다


if(!head || !tail) return false;

10_and 논리곱 문제에서 레퍼런스가 추가되었는데
if(!head || !tail) return false;
이건 무슨 뜻이지?
이거 없이도 잘 돌아가는데..


profile
cloud master가 될 거야! (not 석사)

0개의 댓글