프로그래밍언어/알고리즘

알고리즘 3편 Char 문자열 뒤집기 한판 코틀린(kotlin) 으로 시작하는 문제해결방법

by 앵과장 2021. 9. 13. 14:13
반응형

안녕하세요
앵과장입니다.

모든 문제풀이는 kotlin 으로 진행하겠습니다.
Java 만 하다 보니 좀 다른 언어로 진행해보고 싶었고 앞으로 kotlin으로 개발을 해보고 싶다는 생각도 들어서 알고리즘부터라도 진행해보도록 하겠습니다.

문자열 관련 문제를 풀다 보면 단계적으로 비슷한 부분들을 학습하게 됩니다.

문자열을 char배열로 변경해야 한다든가 또는 대소문자만 가지고 와야 한다든가 뒤집어야 할 때 말입니다.
여러 가지 방법으로 진행할수 있지만 현재 단계는 1단계라는 점 그리고 가장 가볍게 여러가지 생각을 하지 말고 접근하는 법부터 진행해야 합니다.

우선 내가 현재 알고 있는 지식으로 최대한 문제를 접근해봅니다.
그래야 리펙토링을 하더라도 이해가 될 수 있기 때문입니다.

처음에 시간이 오래 걸린다고 해서 너무 좌절하지 마시고 저처럼 이놈에 회사 때려치우고 좋은데 간다라는 마음가짐으로 열심히 하다 보면 어느 순간 성장하고 있는 나를 발견할 수 있습니다.


모든 문제는 Kotlin으로 진행됩니다.
참고하세요

문자열 뒤집기

 

뒤집기 한판

 

오늘의 문제

배열에 들어 있는 단어들을 뒤집어 보세요
여러분들은 주어진 단어들을 뒤집기만 하시면 됩니다.

모든 문장은 영어 알파 팻으로 주어집니다.
fun solution(i, List <String>) 주어집니다.
i는 배열에 길이
List는 아래 배열입니다.

이렇게 주어집니다.
3,["baBo", "apple", "Banna"]

결과물
["baBo", "apple", "Banna"]
["oBab", "elppa", "annaB"]

오늘도 저는 여러가지 생각으로 또 어렵게 문제를 풀었습니다.
아직도 저의 머리는 알고리즘을 풀기에는 한참 모자란가 봐요 ㅜ.ㅜ

생각을 덜어내야 한다고 하는데 좀 더 덜어내 보겠습니다.
Kotlin 언어를 보다 보니 이런 게 있어서 써보고 싶다 보니
풀이가 원하는 방향을 좀 벗어나버렸네요

 fun solution(i: Int,a: List<String>): List<String> {
    var answer = ArrayList<String>()
    var listOfReverse = mutableListOf<String>() 
    a.forEachIndexed{
          index, item-> listOfReverse.add(index,reverse(item)) 
    } 
    answer = listOfReverse as ArrayList<String> return answer 
}
fun reverse(str:String):String{
    val stringToChar = str.toCharArray()
    var listOfTempChar = mutableListOf<Char>()
    stringToChar.forEachIndexed{
        index, charString -> listOfTempChar.add(index,stringToChar.get(stringToChar.lastIndex-index)) 
    } 
    return listOfTempChar.joinToString("") 
}
코틀린 팁


forEachIndexed
index 정보와 value를 함께 사용할 수 있는 순환문입니다.

mutableListOf <Char>
List는 읽기 전용이며 MutableList는 읽기/ 쓰기가 가능합니다.
Kotlin에선 List인 listOf의 사용을 권장하고 있습니다. (코드의 선명함과 안정성 때문에)
하지만 동적으로 할당되는 배열을 활용하기 위해서 MutableList를 사용해야 합니다.

joinToString
1. joinToString : 코틀린에서 배열 데이터 출력 형식을 변경할 때 사용합니다
2. 일반적 출력형식 : 코틀린에서 기본적인 배열 데이터 출력 형식은 [데이터, 데이터, 데이터 ... ] 형식입니다
3. joinToString(구분자, 시작, 종료) 형식으로 사용합니다

다시 좀 더 리펙토링을 해볼까요?
kotlin에서 제공하는 plus를 사용하였습니다.

puls
plus는 배열에 값을 추가할 때 사용합니다.
이걸로 뒤집을 수도 있는 것이지요
하지만 직관적이지는 않습니다. 코틀린에저 제공하는 plus를 사용하다 보니
이해가 되어야 가능합니다.

for for 는 빅오표기법 어찌 되나요

fun solution(i: Int,a: List<String>): List<String> {
    var answer = ArrayList<String>(); 
    for(s in a) {
        var temp = "" for(c in s) {
            temp = c.plus(temp) 
        } 
        answer.add(temp) 
    } 
    return answer; 
}

 

이번에는 함수를 안 쓰고 해 볼까요?
이번에는 배열을 2로 나눴습니다.

우리가 배열을 접근할 때 순차적인 접근방식으로 길이만큼 돌게 되지만
가장 좋은 건 무조건 줄이는 겁니다

이것이 바로 big(o)로 표기하는 이유입니다.
최근 여러 가지 알고리즘 공부를 하는데 빅오를 이해하는데 가장 쉽게 이해한 유튜브중에 하나입니다.
줄기차게 어려운 말로 듣는 거보다는 귀에 속 들어오는 걸로 이해하면 좋겠지요

이분보다 쉽게 예기하는 사람을 아직 찾지 못했습니다. 감사 감사요 니꼴라스~~

until
until은 크기 - 1만큼을 뜻한다.
컴퓨터 배열의 index는 0번째부터 시작합니다. 그냥 컴퓨터 OS가 0,1 되어있다 보니
0이라는 숫자가 상당히 큰 의미를 가지게 됩니다.
근데 배열에 사이즈는 1부터 시작되기 때문에 index로 배열에 찾다 보면 -1이 되어야 하는 경우가 발생하는데
이때 사용합니다.

fun solution(i: Int, a: List<String>): List<String> {
    val answer = ArrayList<String>();
    for (j in 0 until i) {
        val chars = a[j].toCharArray() 
        for (k:Int in 0 until chars.size / 2) {
            val tmp = chars[k] 
            chars[k] = chars[chars.size - k - 1] 
            chars[chars.size - k - 1] = tmp 
        } 
        answer.add(String(chars)) 
    } 
    return answer; 
}

단어를 뒤집기 위해서 반으로 나누고 index들을 서로 바꿔주는 겁니다.
뭐 어렵게 굳이 등가교환이라는 표현을 쓰기도 하는데....
뭐 그건 그렇고..

이렇게 바꾸는 겁니다.
이게 가장 적합할 것 같네요

개발하다 보면 여러가지 방안이 존재하는데 첨부터 최적에 방안으로 가는사람은 많지 않습니다.
여러분도 이렇게 하다보면 하나씩 배워나갈 수 있어요

알고리즘 다음 편 클릭

 

알고리즘 4편 정규표현식 말고 아스키 코드로 문자 숫자 필터링하기 코틀린(kotlin) 으로 시작하는

안녕하세요 앵과장입니다. 모든 문제풀이는 kotlin 으로 진행하겠습니다. 오늘은 문자를 처리할때 알파뱃 대소문자만 필터링할때 또는 숫자만 처리할때 필요한 문자열처리에 대해서 알아보려고

angryfullstack.tistory.com