본문 바로가기
알고리즘/문제

[프로그래머스] [kotlin] 신규 아이디 추천

by 코드 이야기 2021. 4. 3.
728x90


yoggaebi.tistory.com/59

 

[프로그래머스, Kotlin] 신규 아이디 추천

class Solution { fun solution(new_id: String): String { var answer: String = new_id answer = step1(answer) answer = step2(answer) answer = step3(answer) answer = step4(answer) answer = step5(answer..

yoggaebi.tistory.com

처음에 String이 배열인 것으로 착각을 해서 실패했다. 틀리고 나니 String이 기본 데이터타입이 아니라는 것을 그제서야 생각해냈다..

이 블로그를 참고하였다. 각 과정을 함수화 하는 방법도 참고하여 배워야겠다.

또한 step2에서 if문 안에 (it in 'a'..'z') 이렇게 비교하는 방법도 알 수 있었고,

버퍼에 필요한 것만 담아서 사용하는 방법도 알 수 있었다.

 

 

완성한 코드

class Solution {
    fun solution(new_id: String): String {
        var answer: String = new_id

        answer = step1(answer)
        answer = step2(answer)
        answer = step3(answer)
        answer = step4(answer)
        answer = step5(answer)
        answer = step6(answer)
        answer = step7(answer)

        return answer
    }

    private fun step1(new_id: String): String {  //대->소문자
        return new_id.toLowerCase()
    }

    private fun step2(new_id: String): String {  //소문자, 숫자, 일부 특수문자('-', '_', '.')만 허용
        var sb = StringBuffer()

        new_id.forEach {
            if((it in 'a'..'z') || (it in '0'..'9') || it=='-' || it=='_' || it=='.') {
                sb.append(it)
            }
        }

        return sb.toString()
    }

    private fun step3(new_id: String): String {  //.이 연속된다면 .으로 대체
        var result = new_id

        while (result.contains("..")) {
            result = result.replace("..", ".")
        }

        return result
    }

    private fun step4(new_id: String): String {  //처음과 끝이 .이라면 삭제
        var result = new_id

        val indexOfFirst = result.indexOfFirst { it == '.' }
        if(indexOfFirst != -1 && indexOfFirst == 0)
            result = result.replaceFirst(".", "")

        val indexOflast = result.indexOfLast { it == '.' }
        if (indexOflast != -1 && indexOflast == result.length-1)
            result = result.substring(0, indexOflast)

        return result
    }

    private fun step5(new_id: String): String {  //비었다면 a추가
        var result = StringBuffer(new_id)

        if(result.isEmpty())
            result.append("a")

        return result.toString()
    }
    
    private fun step6(new_id: String): String {  //15자 뒤의 것들을 삭제후 끝이 '.'이라면 '.'삭제
        var result = new_id

        if(result.length > 15)
            result = result.substring(0, 15)

        val indexOflast = result.indexOfLast { it == '.' }
        if (indexOflast != -1 && indexOflast == result.length-1)
            result = result.substring(0, indexOflast)

        return result
    }
    
    private fun step7(new_id: String): String {  //문자 길이 3까지 늘이기
        var result = StringBuffer(new_id)

        while (result.length < 3) result.append(result.last())

        return result.toString()
    }
}

 

 

 

 

 

 

문제를 풀며 알게된 것

isUpperCase(), isLowerCase() 를 이용해 문자가 대문자인지, 소문자인지 확인할 수 있다.

toUpperCase(), toLowerCase() 를 이용해 대문자, 소문자로 바꾸어줄 수 있다.

toIntOrNull() 을 이용해 String을 숫자로 바꿀 수 있다면 숫자로 바꿔 반환해주고, 바꿀 수 없다면 null을 반환해준다.

+ ![ListName].isEmpty() 할 필요없이 [ListName].isNotEmpty() 를 해주면 된다.

⭐️리스트를 toString() 해줘봤자 [' ', ' ', ' ', ' '] 이런 형태이다...

 

[ListName].indexOfFirst { it == '.' } 을 하면 '.'이 처음으로 나오는 위치를 반환한다. 만약 없다면 -1을 반환한다.

[ListName].indexOfLast { it == '.' } 을 하면 '.'이 뒤에서 처음으로 나오는 위치를 반환한다. 만약 없다면 -1을 반환한다.

substring을 이용해 (해당 인덱스서 부터 끝까지 || 해당 인덱스서 부터 원하는 인덱스까지) 문자열을 잘라 반환한다.

 

 

 

 

 

더보기

실⭐️패

class Solution {
    fun solution(new_id: String): String {
        var answer: String = ""
        var referralID = new_id.toMutableList()
        var i: Int = 0

        //소문자로 치환
        for (i in referralID.indices) {
            if(referralID[i].isUpperCase()) referralID[i] = referralID[i].toLowerCase()
        }

        //소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거
        //마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환 -> 마침표(.)가 처음이나 끝에 위치한다면 제거
        while (i < referralID.size) {
            if(referralID[i].toString().toIntOrNull() == null) { //숫자가 아니라면
                if (!referralID[i].isLowerCase() && referralID[i] != '-' && referralID[i] != '_' && referralID[i] != '.') {
                    referralID.removeAt(i)
                    i--
                }
            }

            if(i>0) {
                if(referralID[i]=='.' && referralID[i-1]=='.') {
                    referralID.removeAt(i)
                    i--
                }
            }

            i++
        }
        if(referralID.isNotEmpty() && referralID[0]=='.') referralID.removeAt(0)
        if(referralID.isNotEmpty() && referralID[referralID.size - 1]=='.') referralID.removeAt(referralID.size - 1)

        //빈 문자열이라면, "a"를 대입
        if(referralID.isEmpty()) referralID.add(0,'a')

        //15를 초과한다면, 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거
        while (referralID.size > 15) {
            referralID.removeAt(referralID.size-1)
        }
        if(referralID.isNotEmpty() && referralID[referralID.size - 1]=='.') referralID.removeAt(referralID.size - 1)

        //2자 이하라면, 마지막 문자를 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
        while (referralID.size < 3) {
            val lastChar: Char = referralID[referralID.size-1]
            referralID.add(lastChar)
        }

        //todo toString  . ....말고 다른 방법 찾아보자..
        answer = referralID.joinToString()
        return answer
    }
}

 

슬퍼..

 

다른사람 코드를 보니 그냥 바로 new_id에다가 연산을 해주었다.

배열이라 추가 삭제 등 여러 연산을 하기 어렵지않나??!??!? 했는데 2초 후 생각났다. String은 기본 타입이 아니다... . . . .즉 배열이 아니다... ㅏ . ............ 내일 금방 다시 해봐야지..

 

 

728x90

댓글