[Week05][TUE 24 MAY 2022] 자바 재귀 연습문제 페어프로그래밍
몇가지 배운 점, 느낀 점 기록.
자꾸 sum += num; 이런 거 쓰고 싶은 거 어떡하냐..
합을 구하는 문제에서
sum = sum + num;
이렇게 재귀 안 써서 풀고 오류나고..
difficult() 라는 재귀 함수를 쓴다면... 😥
public int difficult(int num){
return difficult(num-1) 연산어쩌구 num;
}
반복하고 싶은 부분에 재귀함수를 쓰면 되는구나~
내가 이해한 게 맞는지 잘 모르겠는데
페어님께 설명하면서 이해한 부분도 있고
오후에 라이브세션 때 설명 들으면 더 잘 이해가 가겠지
이거 반복문에서도 풀었는데
그때 내가 풀었던 방식은
양수일 때는 -2를 하고 음수일 때는 +2을 해서
+1일 때는 true 리턴, 0일 때는 false를 리턴
양수랑 음수로 if문을 나눠서 사용했다.
그런데 이렇게 하면 +1, -1, 0을 다 따로 리턴해줘야하는 문제가 있어서
내 코드는 정말 길었다. ㅋㅋ....
(근데 레퍼런스도 안 찾아봤음 )
오늘도 그렇게 풀려니까 이건 좀 아닌 것 같다..
레퍼런스 참고 ㄱㄱ
(페어할 땐 다 지우고 풀었음!!)
진짜 신박하고 간단한 방법
음수를 양수로 바꿔주면 되는 것이었다 !!!
음수->양수로 바꿈
양수 모두 -2를 계속 해줌
0은 return false
1은 return true
딱 4줄이면 끝나
사람이 이래서 배워야 하는구나
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}) = 없음
이걸 반복하는 것이라고 이해했다.
내가 이해한 게 맞는지 확신이 없어 ㅠ
페어님도 이게 맞는 것 같다고 하셨으니까 일단 넘어감
필요한 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(복사하려는원본, 원본시작인덱스,복사출력대상,복사해와서어느부분부터쓸것인지,원본에서복사본까지어느만큼읽어서쓸것인지)
설명하려니까 진짜 대박 너무 길어
그래도 풀어서 써보니까 이해가 좀 된다네요~~
int arr1 = new int[]{10,20,30,40,50};
int arr2 = new int[3];
System.arraycopy(arr1, 1, arr2, 0, 3);
// -> 결과 {20,30,40}
그려
모든 건 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() 그립다
잘 지내니.. 내 목소리 들리니.. 🐍🐍🐍
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 연산, 둘 중 하나라도 거짓이면 결과는 거짓이다
10_and 논리곱 문제에서 레퍼런스가 추가되었는데
if(!head || !tail) return false;
이건 무슨 뜻이지?
이거 없이도 잘 돌아가는데..