영운's 블로그

[프로그래머스Lv1] 신규 아이디 추천 (Java) 본문

백준 , 프로그래머스 풀이/프로그래머스 Lv1 (Java)

[프로그래머스Lv1] 신규 아이디 추천 (Java)

오영운(you88) 2022. 4. 1. 14:35
 

 

 

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

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

programmers.co.kr

 

대부분의 프로그래머스 Lv1 문제가 그러하듯 이 문제도 특별한 알고리즘적인 지식이 아닌

해당 언어의 기능을 활용하는 능력에 초점을 맞춘 문제이다.

 

이 문제의 경우 정규식을 이용하면 코드를 훨씬 줄여서 만들 수 있다.

 

        new_id = "...!@BaT#*..y.abcdefghijklm.";
        String answer = new_id;
        StringBuffer sb = new StringBuffer();

		/*2단계 소문자, 숫자 , '-', '_', '.' 제외 모든 문자 제거*/
        
        //정규식을 쓰지 않은 경우
        for (int i = 0; i < new_id.length(); i++) {
            if (String.valueOf(new_id.charAt(i)).matches("[a-z0-9-_.]"))
                sb.append(new_id.charAt(i));
        }
        
        //정규식을 쓰는 경우        
        answer = answer.replaceAll("[^a-z0-9-_.]", "");

2단계는 소문자, 숫자, '-' , '_' , '.'을 제외한 모든 문자를 제거한다.

 

정규식을 경우 쓰지 않았을 때 보다 훨씬 코드가 깔끔하고 실행시간 또한 줄어든다.

 

a-z는 소문자 a에서 z까지의 알파벳을

0-9는 0에서 9까지의 숫자를

아무 표시 없이 그냥 해당 문자를 쓰면 해당 문자를 의미한다...

 

[] 안의 ^표시는 [] 안의 기호를 제외한 다른 문자를 의미한다.

주의할 것은 [^a-z0-9-_.]을 하면 a-z가 아닌 다른 문자가 아니라 그 뒤의 모든 표현(a~z, 0~9, '-', '_', '.')이 아닌 문자를 의미한다.

 

        /*4단계 처음이나 끝이 '.'인 경우 '.'제거*/
         
         //정규식 쓰지 않은 경우
        if ((answer.length() != 0) && answer.charAt(0) == '.') {
            if (answer.length() >= 2)
                answer = answer.substring(1);
            else
                answer = "";
        }
        if ((answer.length() != 0) && answer.charAt(answer.length() - 1) == '.') {
            if (answer.length() >= 2)
                answer = answer.substring(0, answer.length() - 1);
            else
                answer = "";
        }
        
        //정규식을 쓴 경우
        answer = answer.replaceAll("^[.]|[.]$", "");

4단계는 처음이나 마지막 문자가 '.'면 이를 지우는 단계이다.

이 단계의 경우 정규식을 사용하면 더 극적으로 코드를 줄일 수 있다.

 

정규식을 이용하지 않으면 길이가 0보다 긴지 확인하는 절차가 필요하다.

정규식은 이러한 절차가 필요하지 않으며 맨 앞, 맨 뒤 '.'이 있는지 한 번에 확인 가능하다.

 

[]바깥의 ^ (^[])은 문자열 맨 앞을 의미한며

[]바깥의 $ ([]$)은 문자열 맨 뒤를 의미한다.

 

따라서

"^[.]|[.]$"

는 문자열 맨 앞 or 문자열 맨 뒤가 '.'인 경우를 가리킨다.

 

2단계, 4단계를 제외한 나머지 단계들은 정규식을 사용하지 않고도 쉽게 구현 가능하다.

 

public class Solution {
    public String solution(String new_id) {
        String answer = new_id;
        /*1단계 대문자 -> 소문자*/
        answer = answer.toLowerCase();

        /*2단계 소문자, 숫자 , '-', '_', '.' 제외 모든 문자 제거*/
        /*
        StringBuffer sb = new StringBuffer();
        new_id = "...!@BaT#*..y.abcdefghijklm.";

        for (int i = 0; i < new_id.length(); i++) {
            if (String.valueOf(new_id.charAt(i)).matches("[a-z0-9-_.]"))
                sb.append(new_id.charAt(i));
        }
        answer = sb.toString();
        */

        answer = answer.replaceAll("[^a-z0-9-_.]", "");

        /*3단계  연속 ..은 하나의 .만 저장*/
        while (answer.contains(".."))
            answer = answer.replaceAll("\\.\\.", "\\.");

        /*4단계 처음이나 끝이 '.'인 경우 '.'제거*/
        /*
        if ((answer.length() != 0) && answer.charAt(0) == '.') {
            if (answer.length() >= 2)
                answer = answer.substring(1);
            else
                answer = "";
        }
        if ((answer.length() != 0) && answer.charAt(answer.length() - 1) == '.') {
            if (answer.length() >= 2)
                answer = answer.substring(0, answer.length() - 1);
            else
                answer = "";
        }
        */
        answer = answer.replaceAll("^[.]|[.]$", "");

        /*5단계 빈문자열이면 "a"추가*/
        if (answer.length() == 0)
            answer = "a";

        /*6단계 16자 이상이면 15자 까지만 저장 + 마지막 문자가 "."이면 제거*/
        if (answer.length() >= 16) {
            answer = answer.substring(0, 15);
            while (answer.charAt(answer.length() - 1) == '.') {
                answer = answer.substring(0, answer.length() - 1);
            }
        }

        /*7단계 길이가 2자 이하면 길이가 3이 될때까지 마지막 문자 붙여넣기*/
        if (answer.length() <= 2) {
            while (answer.length() != 3) {
                char lastChar = answer.charAt(answer.length() - 1);
                answer = answer.concat(String.valueOf(lastChar));
            }
        }
        return answer;
    }

    public static void main(String[] args) {
        Solution sol = new Solution();

        String new_id1 = "...!@BaT#*..y.abcdefghijklm.";
        String new_id2 = "z-+.^.";
        String new_id3 = "=.=";
        String new_id4 = "123_.def";
        String new_id5 = "abcdefghijklmn.p";
        System.out.println(sol.solution(new_id1));
        System.out.println(sol.solution(new_id2));
        System.out.println(sol.solution(new_id3));
        System.out.println(sol.solution(new_id4));
        System.out.println(sol.solution(new_id5));
    }
}
테스트 1
입력값 "...!@BaT#*..y.abcdefghijklm"
기댓값 "bat.y.abcdefghi"
실행 결과 테스트를 통과하였습니다.
테스트 2
입력값 "z-+.^."
기댓값 "z--"
실행 결과 테스트를 통과하였습니다.
테스트 3
입력값 "=.="
기댓값 "aaa"
실행 결과 테스트를 통과하였습니다.
테스트 4
입력값 "123_.def"
기댓값 "123_.def"
실행 결과 테스트를 통과하였습니다.
테스트 5
입력값 "abcdefghijklmn.p"
기댓값 "abcdefghijklmn"
실행 결과 테스트를 통과하였습니다.

 

Comments