[Kotlin/프로그래머스] 24년 1월 3주차 코드카타정리

지혜·2024년 1월 15일

Code_Kata

목록 보기
9/16

✏20240115 월요일

📖공백으로 구분하기 2

  • my_string 문자열에 trim()을 사용하여 전후 공백을 제거해준다.
  • replace()를 사용하여 2개이상 연속된 공백을 "\\s+".toRegex()로 정규식을 만들어주고, " " 공백 하나로 바꿔준다.
  • split(" ")을 통해 공백을 기준으로 분리하고, toTypedArray()로 타입을 맞춰서 반환한다.
class Solution {//나의 풀이
    fun solution(my_string: String): Array<String> {
        return  my_string.trim()
            .replace("\\s+".toRegex(), " ")
            .split(" ")
            .toTypedArray()
    }
}
  • 문제에서 사이 공백이 여러개가 있어서 당황했다. 구글링을 검색해서 2개 이상 연속 공백에 대한 정규식을 찾았다. 바보같은게, 거기서 replace를 사용해서 그걸 그대로 들고왔는데 다른 사람 풀이에 replace를 사용하지 않고 바로 myString.trim().split("\\s+".toRegex()) 식을 작성하여 반환한 풀이가 있었다. ...침착하게 생각하는 버릇을 좀 더 길러야겠다.
  • 이 외에 my_string.split(" ").filter { it.isNotBlank() }.toTypedArray() 풀이도 마음에 남는다. 처음에 split 밖에 몰라서 당황했는데, 무작정 split으로 나누고 그에 대해 filter로 blank를 거르면 되는 거었다. 이거 정도는 아는 지식으로 풀 수 있었을텐데.. 오늘도 반성을 많이 하게 된다.

✏20240116 화요일

📖0 떼기

  • for문에서 indices를 통해 n_str의 인덱스 범위만큼 반복하게 한 후, 해당 인덱스의 n_str값이 0이 아닐 때 substring을 통해 그 인덱스 값부터 마지막까지 자른 값을 answer에 담고, break를 통해 for문을 빠져나간다. 마지막으로 answer를 반환한다.
class Solution {//나의 풀이
    fun solution(n_str: String): String {
        var answer: String = ""
        for(i in n_str.indices){
            if(n_str[i] != '0'){
                answer =n_str.substring(i)
                break
            }
        }
        return answer
    }
}
  • 쉬운 문제를 혼자서 어렵게 푼 케이스.. 그냥 toInt()로 써서 숫자로 바꾸고 다시 string타입으로 맞춰주기만하면 될 것을 이렇게 돌아돌아 왔다. ...ㅎ

📖0 떼기 문제의 다른 사람 풀이

  1. trimStrat( )를 활용한 방법
class Solution {//다른 사람 풀이
    fun solution(n_str: String) = n_str.trimStart('0')
}
  • trimStart( ) : 앞 부분의 해당하는 괄호 안 문자열만 지우기 가능. 빈칸인 경우 공백을 지운다.
  • trim을 생각했었는데, 맨날 빈칸으로 공백제거만 했었어서,, 저 괄호 안에 뭐 넣을 생각을 못했다. 시도라도 해볼껄.. 근데 trim만 스쳐지나갔지 trimStart trimEnd까지는 솔직히 몰랐는데, 시도해봤으면 쉽게 찾아낼 것들이라서 더 아쉽다.
  1. dropWhile{ }을 사용한 방법
class Solution {//다른 사람 풀이
    fun solution(n_str: String): String {
        return n_str.dropWhile { it == '0' }
    }
}
  • dropWhile{ 조건식 } : 조건을 만족하지 않은 문자가 나올 때까지 제거
  • drop( Int: n ) : 앞에서부터 n개의 문자를 제거한 String을 반환
  • take 처음 쓸 때 drop도 같이 배웠었는데, take는 n개 만큼 취한부분을 반환한다면 drop은 n개 만큼 제거하고 나머지를 반환한다.
  • 사실 초반에 풀이를 할 때에는 어제 푼 공백 구분 처럼 정규식을 쓰려고 했었는데, 이게 나를 수렁으로 빠져들게한 원인이었던 것 같다. ㅎ filter도 조금 생각했었는데, 식을 쓸 엄두가 잘 나지 않아서 외면했는데. 다른 사람풀이에도 없는 걸보니.. (dropWhile이 아마 내가 생각한 필터 역할을 하고 있는 것 같다.) 그래도 오늘 처럼 쉬운 문제를 돌아돌아 오면 조금 현타가 오긴한다.ㅎ

✏20240117 수요일

📖가까운 1 찾기

  • indexOf(char:찾을문자, int:시작할 인덱스)를 사용하기 위해 arr을 문자열로 바꿔준다.
  • answer.indexOf('1',idx)을 사용하여 idx인덱스부터, (문자열로 바꾸었기 때문에 그냥 1이 아니라) '1'을 찾아서 해당인덱스를 반환한다.
class Solution {//나의 풀이
    fun solution(arr: IntArray, idx: Int): Int {
        var answer = arr.joinToString("")
        return answer.indexOf('1',idx)
    }
}
  • 배열에 적용하는 indexOf는 매개변수를 찾을 요소에 대해 딱 하나만 받는다. 문자열만이 매개변수 2개를 허용해준다. 처음에 indexOf(char:찾을문자, int:시작할 인덱스)를 딱 찾고 쉽네~ 했는데 적용했을 때 인자가 너무 많다는 오류를 만나고 폭풍같이 구글링을 돌려 오직 문자열에만 해당되는 것을 알고.. joinToString("")쓰면 되잖아~ 쉽네~ 했다가 '1'이 아니고 그냥 1을 찾았다가 또 오류 폭탄을 맞고.. 오류를 열심히 해석해서 겨우 풀었다. 어쨌든 문자열에서는 범위를 지정해서 indexOf를 사용할 수 있다는 점을 배웠다!

📖인덱스 바꾸기

  • 서로 바꿀 인덱스를 기준으로 front, middle, back을 선언하여 앞부분, 중간부분, 뒷부분을 할당해 놓고,
  • 앞 + num2인덱스값 + 중간 + num1인덱스값 + 뒤 를 이어붙여 반환했다.
class Solution {//나의 풀이
    fun solution(my_string: String, num1: Int, num2: Int): String {

        var front = my_string.substring(0,num1)
        var middle = my_string.substring(num1+1,num2)
        var back = my_string.substring(num2+1)
        
        return front+my_string[num2]+middle+my_string[num1]+back
    }
}
  • 이렇게 한땀 한땀 이어 붙이고 다른 사람 풀이를 보니까 my_string.toCharArray()를 사용하여 중간에 임시 공간을 선언하거나, 변수를 만들어서 바꿔야할 값들을 저정한 다음 해당인덱스값에 새로 할당해주는 방법들이 보였다. 이렇게 풀었으면 안 창피했을 것 같은데..ㅎ 내가 푼.. 방법도.. 단순한 면에선..... 단순하다고.. 생각한다..ㅎ

📖인덱스 바꾸기 문제의 다른사람 풀이 : Collections.swap( )을 사용한 풀이

import java.util.*
class Solution {//다른 사람 풀이
    fun solution(my_string: String, num1: Int, num2: Int): String {
        var str = my_string.toList()
        Collections.swap(str,num1,num2)
        return str.joinToString("")
    }
}
  • java.util을 임포트하여 Collections.swap(List: 지정 할 리스트 ,Int: 바꿀인덱스1,Int :바꿀인덱스2)를 사용할 수 있다.
  • 맨 처음에 이렇게 바로 자리를 바꾸는 함수를 찾아봤는데, 쉽게 나오지 않아서 포기했었더니 역시 다른 분들이 찾아내서 풀이하신게 있었다. 이름도 상당히 직관적이라서 못찾은게 좀 아쉽다. 임포트 해야하고, 컬렉션에서만 사용가능하지만, 단순한 면에서 아주 좋은 것 같다.

✏20240118 목요일

📖x 사이의 개수

  • count변수를 만들어서 for문을 통해 myString을 돌다가 x가 아니면 count에 +1을 하고, x를 만나면 저장된 count 값을 answer에 넣고 count를 초기화하는 것을 반복한다.
  • 반복문이 끝나면 마지막 x 이후의 count 값을 answer에 추가해준 후, answer를 반환한다.
class Solution {//나의 풀이
    fun solution(myString: String): IntArray {
        var answer: IntArray = intArrayOf()
        var count = 0
        for(c in myString) {
            if(c != 'x') {
                count +=1
            } else {
                answer += count
                count = 0
            }
        }
        answer += count
        return answer
    }
}
  • 나눈다. 라는 단어를 보고 당연히 split이 떠올랐지만, 무슨 일인지 x로 나누면 길이에 x도 포함되어서 나눈 문자열의 길이가 +1될거라고 생각했다. 그래서 for문을 돌렸는데, 다른사람 풀이를 보니까 myString.split("x").map { it.length }.toIntArray() 그냥 it.length를 사용해서 풀었다. ㅎ
  • split() : 괄호안의 값을 구분자로 분리하여 문자열을 분리해준다. 구분자의 앞이나 뒤가 공백이여도 전부 표시해준다.
  • split이라는 함수를 제대로 이해하지 못하고 있었던 것 같다. 오늘을 기점으로 특성을 제대로 알아놔야겠다.

📖특별한 이차원 배열2

  • 이차원 배열이지만, arr의 길이와 arr의 원소의 길이는 똑같기 때문에 i와 j모두 arr의 인덱스 범위만큼 반복하도록 arr.indices를 사용했다.
  • 이중 for문을 통해 arr[i][j]arr[j][i]이 똑같은지 아닌지를 확인하는 것이기 때문에 똑같지 않은 것을 찾아서 있다면 그 순간 answer에 0을 할당하고 break로 반복문을 빠져나오도록 했다.
  • 만약 전부 동일하다만 초기화 값인 1이 answer을 통해 반환되고, 하나라도 틀린 값이 있다면 0이 반환되도로 했다.
class Solution {//나의 풀이
    fun solution(arr: Array<IntArray>): Int {
        var answer: Int = 1
        for(i in arr.indices){
            for(j in arr.indices){
                if(arr[i][j] != arr[j][i]){
                    answer = 0
                    break
                }
            }
        }
        return answer
    }
}

📖특별한 이차원 배열2 문제의 다른 사람 풀이: all과 compareTo를 활용한 풀이

class Solution {//다른 사람 풀이
    fun solution(arr: Array<IntArray>) 
    = arr.indices.all {i -> arr.indices.all { j ->
    arr[i][j] == arr[j][i] } }
    .compareTo(false)
}
  • all() : 함수의 모든 원소가 람다식을 만족하는지 체크할 수 있다.
  • compareTo() : 호출객체와 괄호 안에 있는 전달된객체를 비교하여 둘이 같으면 0, 전달된 객체가 더 크면 음수(-1), 전달된객체가 더 작으면 양수(1)를 반환한다.
  • all 함수를 통해 i와 j 전부에 대해 {arr[i][j] == arr[j][i]}를 충족하는지 체크하고, compareTo(false)를 통해서는 조건{arr[i][j] == arr[j][i]}을 충족하는지 평가한 후에 false와 일치하면 즉, 일치하지 않으면 0을 반환하고, false(=0)와 일치하지 않으면 즉, true(=1)로 일치하면 true가 더 크기 때문에 양수 1을 반환한다.

✏20240119 금요일

📖특별한 이차원 배열 1

  • answer에 배열의 크기를 초기화 한 다음, 이중for문을 통해 i와j의 값이 서로 다르면 0을 같으면 1을 할당하게 작성하여 answer에 담아 반환한다.
class Solution {//나의 풀이
    fun solution(n: Int): Array<IntArray> {
        var answer: Array<IntArray> = Array(n) { IntArray(n) }

        for(i in 0.. n-1){
            for(j in 0 .. n-1){
                if(i != j) answer[i][j] = 0
                else answer[i][j] =1
            }
        }
        return answer
    }
}
  • 배열..너무 어렵다.. 맨날 얼렁뚱땅 값 집어 넣기만 했다가, 오늘 이차원배열을 만나고 민낯이 드러났다.. 배열 초기화를 하는데 타입이 너무 안맞아서 고생했다. 오늘 따라 오류 문장도 잘 해석하지 못한 것 같다. 그래서 더 헤맸다.

📖IntArray와 Array 차이 (참조 블로그 : 코틀린 IntArray와 Array 차이)

  • IntArrayint[]로 변환되고, Array<Int>Integer[]로 변환된다.
    둘의 차이는 Integer변수에 int를 저정하면 int형을 Integer로 변환하여 저장한다.(=boxing)
  • 초기화 할 때에도 IntArrayIntArray(초기화크기)로 만 적어도 알아서 0으로 초기화 해주지만, Array<Int>Array<Int>(초기화크기){0}으로 따로 초기화할 값도 지정해줘야한다. 크기만 저정하면 안된다.
  • 따라서 나의 풀이 에서도 0값을 따로 넣어줄 필요없이 if(i == j) answer[i][j] =1 i와 j가 같은 경우에만 1로 값을 변경해줘도 충분한 것이 었다.

📖특별한 이차원 배열 1 문제의 다른 사람 풀이 : 람다식을 이용한 풀이

class Solution {
  fun solution(n: Int): Array<IntArray> {
      return Array(n) { i -> IntArray(n) { j -> if (i == j) 1 else 0 } }
  }
}
  • 람다식 안에서 초기화 값을 설정할 수 있다. i(j)는 초기화한 크기 만큼 0부터 1씩 커진다.
  • 여기선 n만큼 i와 j값이 진행되면서 i와j가 같지않으면 0을 같으면 1을 값으로 가져 반환된다.
  • 볼 때는 그렇지~ 라고 생각하지만 막상 내손으로 쓰려면 제일 안써지는게 배열같다. 사실 아직도 배열에 값 넣는거는 +=을 쓰지 못하면.. 여러곳을 헤매게된다... 그래도 오늘 정리하면서 IntArray는 초기화를 안해도 자동으로 해준다던지 등에 대해 한 번 더 새길 수 있는 계기가 된 것 같다. 솔직히 배열은 더 많이 만져보는 것 밖에는 수가 없는 것 같다. 막힐 때마다 이론을 검색하지만... 이론은 맨날 똑같고 보면 아는 내용인데 왜 이렇게 풀이로 응용하는 것은 어려운지... 이차원배열도 오늘 처음이나 다름 없으니까 더 당황스러운거였다고 믿겠다..ㅎㅎ
profile
파이팅!

0개의 댓글