상속

부모 클래스에서 중복되는 메소드 가져오기

Chicken의 fly 메소드 사용이 가능해졌다. 상속받으려면 부모클래스에서 open해주어야 한다.

open class Bird {
	fun fly()
}

class Chicken : Bird() {

}

 

override 오버라이딩

부모클래스에서 특정메소드 커스텀해서 쓰고 싶을때 사용.

open class Bird(name) {
	open fun fly() {
    }
}


class Chicken(name: String, age: Int) : Bird(name) {
	override fun fly() {
    }
}

 

overload 오버로드

매개변수의 갯수 또는 자료형만 다른녀석인데 동일한 이름으로 쓰면 안되나 해서 나온 녀석(가능하다.)

class calculator {
	fun add(num1:Int, num2:Int){
    }
    	fun add(num1:DouBle, num2:DouBle){
    }
}

 

Interface 인터페이스 

코틀린은 반드시 한 개의 부모클래스만 상속받을 수 있다.

따라서 근본적인 공통점을 상속 받고, 추가적인 기능들은 인터페이스로 추가한다.

추상 메소드 -> 로직이 존재하지 않고 이름만 존재할 때 추상 메소드라 부른다.

기본적으로 인터페이스는 추상메소드만 작성하는게 원칙이나 최근에는 아니여도 괜찮다는 흐름.

왜 추상메소드로 작성하냐 -> 어차피 자식 클래스에서 오버라이딩해서 작성할거니까

interface 인터페이스이름 {
	fun 메소드이름()
}
class Duck(name: String) : Bird(name), WaterBirdBehavior {
	override fun swim() {
    }
}

 

https://school.programmers.co.kr/learn/courses/30/lessons/134240

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

 

class Solution {
    fun solution(food: IntArray): String {
        var answer: String = ""
        var numArr = food.slice(1..food.size-1).map{it/2}
        var foodList = mutableListOf<Int>()
        
        for(i in numArr.indices) {
            for(j in 0 until numArr[i]) {
                if(numArr[i] != 0) {
                    foodList.add(i+1)
                }
            }
        }
        
        answer = foodList.joinToString("") + '0' + foodList.reversed().joinToString("")
        return answer
    }
}

 

코드를 먼저 보자.

 

우선 , 물을 제외하고 음식 부분의 배열만 먼저 slice로 가져온 뒤 2로 나눠 정수 부분으로 가져왔다.

 

그 후 정수 숫자 만큼 인덱스 숫자를 찍어주고 나온 리스트를 '0'과 그 역순의 리스트와 합쳐줘서 반환해준다.

 

별로 어렵지 않은 문제였다.

 

다만 코틀린스럽게 풀지는 못했다...

내가 제출한 코드

class Solution {
    fun solution(numbers: IntArray): IntArray {
        var answer: IntArray = intArrayOf()
        var intset = mutableSetOf<Int>()
        
        for(i in 0 until numbers.size - 1) {
            for(j in i+1 until numbers.size) {
                intset.add(numbers[i] + numbers[j])
            }
        }
        answer = intset.sorted().toIntArray()
        return answer
    }
}

 

이중for문을 이용해서 더해주었고 원소가 중복되면 안되기에 Set를 사용했다.

 

내 생각 코틀린스럽게 푼 사람 (사실 코틀린스럽다는 말을 정확히 몰라 틀릴 수 있음,,)

뭔가 코틀린 함수 쓴게 코틀린스러운건가,,ㅎㅎ

다른 분의 코드

class Solution {
    fun solution(numbers: IntArray): IntArray {
        val list = numbers.toList()
        return list.withIndex().flatMap { i -> list.withIndex().map { j -> i to j } }
            .filter { it.first.index != it.second.index }
            .map { it.first.value + it.second.value }
            .toSortedSet()
            .toIntArray()
    }
}

 

분석해보면 공부에 도움이 될거 같아 분석한번 해보겠습니다.

 

분석에 앞서 필요한 확장함수를 조금 알아보고 가자.

.withIndex() -> 객체의 원소를 (index, value) 형태로 접근할 수 있게 해준다.

예) list = listOf("a", "b", "c")

      indexedList = list.withIndex() 

      print(indexedList)

[IndexedValue(index=0, value=a), **IndexedValue(index=1, value=b)**, IndexedValue(index=2, value=c)]

 

이런식으로 출력된다.

 

.flatMap -> 컬렉션 안에 컬렉션이 있을 경우 내부 컬렉션을 펼쳐주는 연산이며 .map과 다르게 1대1매핑이 아닌 1대 多 매핑이 가능하다. 즉 모든 요소들의 생성값을 다룰 수 있다. 

 

.filter -> 간단히 필터 조건문안에 조건을 만족하는 원소들만 받아서 가져오겠다는거다.

 

이제 코드를 하나하나 뜯어보자. (너무 깊숙이 뜯진 못한다,,)

 

val list = numbers.toList()

numbers를 리스트 형태로 바꾸어 list에 담아준다.

 

list.withIndex().flatMap { i -> list.withIndex().map { j -> i to j } }

 

이 부분이 이해하기 굉장히 어려웠던 부분이었다. 사실 완벽하게 이해한 것인지는 모르나 틀렸을 경우 댓글부탁드립니다.

우선 문제의 첫 번째 입출력 예인 [2,1,3,4,1] 을 입력값으로 해서 예시로 사용해보겠다.

 

withIndex() 를 통해 [(0,2) (1,1) (2,3) (3,4) (4,1)] 이런식의 원소의 인덱스와 실제 value가 포함된리스트가 반환된다.

 

flatMap() 을 통해 이 안에 원소들을 1대 다 매핑이 가능하게 만들어줌과 동시에 마지막엔 싱글리스트로 반환해준다.

.map{} 안에 "i to j"는 i와 j를 pair시켜주는 역할이다. 

 

[(0,2) (1,1) (2,3) (3,4) (4,1)] 이 리스트의 i로 돌아가는 반복문과 list.withIndex().map의 j 인덱스로 돌아가는 반복문으로 

j가 i를 기준으로 각 원소를 순회하며 i to j를 실행한다. 가독성을 위해 많은 띄어쓰기를 넣었습니다...

 

[(0,2) (0,2)    ,     (0,2) (1,1)    ,    (0,2) (2,3)   ,   (0,2) (3,4)    ,  (0,2) (4,1)]

 

마찬가지로 다음 i 원소인 (1,1)을 기준으로 실행

[ (1,1) (0,2)   ,     (1,1)  (1,1)    ,   (1,1) (2,3)   ,   (1,1) (3,4)    ,    (1,1)  (4,1)]

 

이런식으로 하면 반복하면 

[(0,2) (0,2)    ,     (0,2) (1,1)    ,    (0,2) (2,3)   ,   (0,2) (3,4)    ,  (0,2) (4,1)

(1,1) (0,2)   ,      (1,1)  (1,1)   ,    (1,1) (2,3)   ,   (1,1) (3,4)    ,  (1,1)  (4,1)

(2,3) (0,2)   ,      (2,3)   (1,1)   ,   (2,3)  (2,3)  ,   (2,3) (3,4)    ,  (2,3)   (4,1)

(3,4) (0,2)   ,      (3,4)   (1,1)   ,   (3,4)  (2,3)   ,  (3,4) (3,4)    ,  (3,4)   (4,1)

(4,1) (0,2)   ,      (4,1)   (1,1)   ,   (4,1)  (2,3)   ,   (4,1) (3,4)    ,  (4,1)   (4,1)]

 

이런식의 리스트가 반환됩니다.

 

.filter { it.first.index != it.second.index }

 

서로 다른 인덱스의 있는 두 수를 더해주기 위해서는 이 리스트에서 filter를 통해 (0,2)(0,2) , (1,1)(1,1) , (2,3)(2,3) ,  (3,4) (3,4)  , (4,1)(4,1) 과 같은 인덱스 값이 같은 원소들을 제외하고 인덱스 값이 다른 원소들만 걸러줍니다.

 

[                  ,     (0,2) (1,1)    ,    (0,2) (2,3)   ,   (0,2) (3,4)    ,  (0,2) (4,1)

(1,1) (0,2)   ,                           ,    (1,1) (2,3)   ,   (1,1) (3,4)    ,  (1,1)  (4,1)

(2,3) (0,2)   ,      (2,3)   (1,1)   ,                        ,   (2,3) (3,4)    ,  (2,3)   (4,1)

(3,4) (0,2)   ,      (3,4)   (1,1)   ,   (3,4)  (2,3)   ,                        ,  (3,4)   (4,1)

(4,1) (0,2)   ,      (4,1)   (1,1)   ,   (4,1)  (2,3)   ,   (4,1) (3,4)    ,                      ]

 

.map { it.first.value + it.second.value }

 

원소들의 value 를 합해준 리스트를 반환합니다.

[3, 5, 6, 3, 

3, 4, 5, 2,

5, 4, 7, 4,

6, 5, 7, 5,

3, 2, 4, 5] 

 

.toSortedSet()

 

Set 컬렉션의 가장 큰 특징인게 중복된 원소가 없는 없다는것입니다.

toSortedSet() 으로 set 컬렉션형태로 바꾸고 오름차순으로 정렬해줍니다.

 

그리고 마지막은 반환형태에 맞게 toIntArray()로 맞춰줍니다.

 

끄읕

 

c 코드로 짜면 이중 for문이 들어가게 짤 텐데.. 코틀린은,,

class Solution {
    fun solution(array: IntArray, commands: Array<IntArray>): IntArray {
        var answer = intArrayOf()
        answer = commands.map{ array.slice(it[0]-1 until it[1]).sorted()[it[2]-1] }.toIntArray()
        return answer
    }
}

 

한 줄로 코틀린스럽게,,,

 

우선 map으로 원소 하나 하나에 접근을 해주고 slice로 배열의 원하는 만큼 짤라서 정렬시켜주고 그 배열의 특정 인덱스 값 원소를 가져와서 IntArray로 바꿔서 리턴해준다.

 

 

 

처음에는 map으로 처리를 할까 하였으나 인덱스 값을 따져가며 하는게 비효율적이라 생각되어 고민을 좀 했다.

 

문자열 안에서 숫자는 냅두고 영단어만 숫자로 바꿀 순 없을까 하다가 찾은게 replace()

replace(바꿀녀석, 원하는결과) 이런식으로 쓰면 된다.

 

우선 코드를 보자.

 

class Solution {
    fun solution(s: String): Int {
        var answer : Int = 0
        val numArr = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven","eight", "nine")
        var temp = s
        for (i in 0 until numArr.size) {
            temp = temp.replace(numArr[i], i.toString())
        }
        answer = temp.toInt()
        return answer
    }
}

 

 

영단어를 배열에 넣어 반복문으로 해당하는 영단어가 있으면 그 영단어가 있었던 인덱스 값을 문자열값으로 넣어준다.

 

여기서 신경써줘야 할건 숫자를 배열에 순서대로 넣어준다는 것! one zero four two nine --- 이런식으로 넣으면 안된다. 또한 반복문의 조건식도 신경써서 넣어주어야한다.

 

배열을 잘 쓰면 까다로울 수 있는 문제도 쉽게 해결 가능하다는 걸 느낀 문제다.

 

 

+ Recent posts