영운'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