[Programmers] 신규 아이디 추천 - Java

2021. 12. 11. 18:21Computer Sciences/Problem Solve

https://programmers.co.kr/learn/courses/30/lessons/72410

 

코딩테스트 연습 - 신규 아이디 추천

카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로

programmers.co.kr

문제를 보자마자 정규식을 써서 풀어야 될 거라고 생각했다. 자바에서는 replaceAll()이라는 함수로 정규식을 이용해 문자열을 치환할 수 있다. 정규식을 알면 어렵지 않게 풀 수 있는 문제다.

정규식은 간략하게 정리하면 다음과 같다. 자바에서 정규식을 쓸 때 주의할 점은 정규식 기호를 문자로 매칭하려면 백슬래시(\)를 두 개 붙어줘야 한다.

Groups and ranges

| 또는

() 그룹

[] 문자셋, 괄호안의 어떤 문자든

[^] 부정 문자셋, 괄호안의 어떤 문이 아닐 때

(?:) 찾지만 기억하지는 않음

Quantifiers

? 없거나 있거나 (zero or one)

* 없거나 있거나 많거나(zero or more)

+ 하나 또는 많이 (one or more)

{n} n번 반복

{min, } 최소

{min,max} 최소, 그리고 최대

Boundary-type

\b 단어 경계

\B 단어 경계가 아님

^ 문장의 시작

$ 문장의 끝

Charactor classes

\ 특수 문자가 아닌 문자

.(dot) 어떤 글자(줄바꿈 문자 제외)

\d digit 숫자

\D digit 숫자 아님

\w word 문자

\W word 문자 아님

\s space 공백

\S space 공백 아님

class Solution {
    public String solution(String new_id) {
        String s = new_id;

        // 1단계
        s = s.toLowerCase();

        // 2단계
        s = s.replaceAll("[^a-z0-9\\-_.]*", "");

        // 3단계
        s = s.replaceAll("\\.{2,}", "\\.");

        // 4단계
        s = s.replaceAll("^[.]|[.]$", "");

        // 5단계
        if (s.equals("")) {
            s = "a";
        }

        // 6단계
        if (s.length() >= 16) {
            s = s.substring(0, 15);
        }

        s = s.replaceAll("[.]$", "");

        // 7단계
        if (s.length() < 3) {
            while(s.length() != 3) {
                s += s.substring(s.length() - 1);
            }
        }

        return s;
    }
}

다른 사람의 답을 보다가 빌더 패턴으로 구현한 것을 보았는데 깔끔하고 자바다웠던 코드라서 인상깊었다. 해당 코드도 공유하도록 하겠다.

class Solution {
    public String solution(String new_id) {

        String s = new KAKAOID(new_id)
                .replaceToLowerCase()
                .filter()
                .toSingleDot()
                .noStartEndDot()
                .noBlank()
                .noGreaterThan16()
                .noLessThan2()
                .getResult();


        return s;
    }

    private static class KAKAOID {
        private String s;

        KAKAOID(String s) {
            this.s = s;
        }

        private KAKAOID replaceToLowerCase() {
            s = s.toLowerCase();
            return this;
        }

        private KAKAOID filter() {
            s = s.replaceAll("[^a-z0-9._-]", "");
            return this;
        }

        private KAKAOID toSingleDot() {
            s = s.replaceAll("[.]{2,}", ".");
            return this;
        }

        private KAKAOID noStartEndDot() {
            s = s.replaceAll("^[.]|[.]$", "");
            return this;
        }

        private KAKAOID noBlank() {
            s = s.isEmpty() ? "a" : s;
            return this;
        }

        private KAKAOID noGreaterThan16() {
            if (s.length() >= 16) {
                s = s.substring(0, 15);
            }
            s = s.replaceAll("[.]$", "");
            return this;
        }

        private KAKAOID noLessThan2() {
            StringBuilder sBuilder = new StringBuilder(s);
            while (sBuilder.length() <= 2) {
                sBuilder.append(sBuilder.charAt(sBuilder.length() - 1));
            }
            s = sBuilder.toString();
            return this;
        }

        private String getResult() {
            return s;
        }
    }
}