코틀린/코딩테스트

코딩테스트 [배열 두배 만들기]

정혜현 2024. 6. 7. 20:07

문제

정수 배열 numbers가 매개변수로 주어집니다. numbers의 각 원소에 두배한 원소를 가진 배열을 return하도록 solution 함수를 완성해주세요.


 

풀이

1. 접근

1.1 관찰

기능 : numbers 배열 각 요소에 2를 곱한다. answer 배열에 담는다.

반환 : answer 배열을 리턴한다.

 

 

 

 

2. 시행착오

2.1 시도

  • 가설 : 반복문 for문으로 배열 내 각 요소를 조건으로 설정하고, 배열 내 각 요소에 2를 곱해주면 될 것이다.
class Solution {
    fun solution(numbers: IntArray): IntArray {
        var answer: IntArray = intArrayOf()
        for (i in numbers) {i*2}
        return answer
    }
}

 

  • 검증 : 실패

오류는 없으나 제대로 동작하지 않는다. answer 배열에 값이 담기지 않는다. 

 

문법공부를 해도 대부분 print 하는 방법만 가르쳐줘서 배열과 인덱스에 대한 개념이 부족했다. 좀 더 알아보고 다시 해보기로 한다. 

 

 

범위 지정 : (i in 범위)
i 는 인덱스 또는 요소. in부터는 범위. 범위는 배열명.indices(유효한 인덱스 크기)로 지정하거나 in 0 until 배열명.size(배열의 크기)로 지정한다.
범위에 배열명만 입력하면 i는 인덱스가 아니라 요소라 인덱스를 찾아 반복하지 못한다.
또한 인덱스는 0부터 시작하므로 until 없이 배열의 크기로만 입력하면 인덱스 숫자보다 1 커서 초과된다. 

요소 가리키기 : 인덱스명[i]
배열 안의 인덱스번째 요소를 가리킨다.

 

 

class Solution {
    fun solution(numbers: IntArray): IntArray {
        var answer: IntArray = intArrayOf()
        for (i in numbers.indices){
            answer[i] = numbers[i]*2}
        return answer
    }
}

 

위 코드는 아니고 for문 안으로 answer[i]대신 return answer을 넣는 건 안되나 살펴보니

"a 'return' expression required in a function with a block body" : 함수의 본문이 블록 형태인 경우 return 키워드를 사용해야 된다는 오류가 나오고 또한 for문은 1회 담고 반복문이 즉시 종료되는 형태가 된다. 

 

범위도 바꿨고 각각의 요소를 대체하면 될 것 같은데 오류가 발생한다.

ArrayIndexOutOfBoundsException :  배열의 인덱스 범위를 초과하여 접근하려고 할 때 발생하는 오류

 

intArrayOf가 초기화 되어있지 않아 크기가 0인 상태라고 한다. 그렇다고 intArrayOf(numbers.size)해주면 배열의 크기가 늘어나는 게 아니라 numbers.size라는 요소가 담긴 크기 1의 배열이 된다.

Array는 크기를 정해서 생성하는 배열이고 ArrayOf는 값을 담을 때 크기가 정해지는 배열이라고 한다.

 

for문 (i in numbers.indices){answer[i] = numbers[i]*2}을 살리려면 Array로 써야한다. 

class Solution {
    fun solution(numbers: IntArray): IntArray {
        var answer = IntArray(numbers.size)
        for (i in numbers.indices){
            answer[i] = numbers[i] * 2}
        return answer
    }
}

 

intArrayOf()를 살리려면 반복문을 수정해야 한다. 전개연산자(spread연산자)라는 걸 사용해야된다. 배열 앞에 *을 붙여 나타내며 배열을 풀어헤쳐서 해당 배열의 각 요소를 개별적인 인자로 전달한다. 배열끼리 전달시에는 크기가 다르면 전달할 수 없다. 

class Solution {
    fun solution(numbers: IntArray): IntArray {
        var answer: IntArray = intArrayOf()
        for (i in numbers.indices){
            answer = intArrayOf(*answer, numbers[i] * 2)}
        return answer
    }
}

 

전개연산자 없이 담으면 어떻게 될까? 

class Solution {
    fun solution(numbers: IntArray): IntArray {
        var answer: IntArray = intArrayOf()
        for (i in numbers.indices){
            answer = intArrayOf(numbers[i] * 2)}
        return answer
    }
}

 

각 인덱스 숫자에 2를 곱한 값이 담기기까지 하는데 문제는 덮어쓰여진다. 가장 마지막 숫자에 2를 곱해준 값만 남는거다.

초기 코드를 살렸다는 점은 좋지만 가독성이 좋아보이지 않아 좀 더 개선할 수 있는지 찾아보기로 했다. 전개 연산자 없이 제일 깔끔하게 담는 방법은 +=연산자를 쓰면 된다. 사실 처음부터 이 방법을 쓰고 싶었는데 쓸 줄 몰라서 이렇게나 돌아온거다.....복합대입연산자를 배웠는데 쓰지를 못하니.....김첨지식 코딩을 하는 정혜현......좌항 = 우항+좌항 이란 의미이다. 

class Solution {
    fun solution(numbers: IntArray): IntArray {
        var answer: IntArray = intArrayOf()
        for (i in numbers.indices){
            answer += numbers[i] * 2}
        return answer
    }
}

 

 

Q. 반복문 돌면서 배열 크기가 어떻게 점점 커질 수가 있나?

팀원A. += 복합대입연산자를 사용할 때 배열에 추가하는 게 아니라 새 배열을 만들어 주는 것


회고

정말 유용하고 많이 쓰이는데!!! 필요성도 알겠고 대중성도 인정하는데!!! 활용하는 방법을 몰라서 도저히 다가갈 수 없었던 배열. 많이 써보고 많이 배울게 친해지자 우리

 

 

 

 

'코틀린 > 코딩테스트' 카테고리의 다른 글

코딩테스트 [피자 나눠먹기(1)]  (0) 2024.06.11
코딩테스트 [배열의 평균값]  (0) 2024.06.11
코딩테스트 [분수의 덧셈]  (0) 2024.06.07
코딩테스트 [각도기]  (0) 2024.06.05
코딩테스트 [나이 출력]  (0) 2024.06.05