ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스 72410] 신규 아이디 추천 (java)
    알고리즘 문제 풀기 2021. 4. 22. 17:17

    출처

    나의 코드

    import java.util.StringTokenizer;
    
    class Solution {
        public String solution(String new_id) {
            String answer = "";
            String eraseChar = "~!@#$%^&*()=+[{]}:?,<>/";
    
            while(true) {
                // 1단계 : 소문자화
                // 2단계 : !, @, #, * 제거
                StringTokenizer st = new StringTokenizer(new_id.toLowerCase(), eraseChar);
                while(st.hasMoreTokens()){
                    answer += st.nextToken();
                }
    
                // 3단계 : ... 이랑 .. 을 . 하나로
                // 4단계 : 앞 뒤 . 제거
                st = new StringTokenizer(answer, ".");  // .을 통한 토큰분리
    
                if (st.countTokens() > 1) {
                    // 2개 이상일 경우
    
                    answer = st.nextToken();
                    while (st.countTokens() > 0) {
                        answer += "." + st.nextToken();
                    }
    
                }
                else if (st.countTokens() == 1) {
                    // 1개만 있으면
                    answer = st.nextToken();
                }
                else {
                    // 0개일 경우 (= . 으로만 구성된 문자열
                    answer = "";
                }
    
                // 5단계 : 빈 문자열이면 "a" 추가
                if (answer.isEmpty()) {
                    answer += "a";
                }
    
                // 6단계 length 15까지 잘라냄
                if (answer.length() > 15) {
                    answer = answer.substring(0, 15);
                }
    
                // 7단계 길이가 3 이하면 마지막 글자 반복
                while(answer.length() < 3) {
                    answer += answer.substring(answer.length()-1);
                }
    
                if (new_id.equals(answer)) {
                    return answer;
                }
                else {
                    new_id = answer;
                    answer = "";
                }
            }
        }
    }

    이것도 하드코딩의 향이 난다. 적혀있는대로 작업을 반복하면서 진행한다. 이 코드에서 주의해야할 점은

    • 내가 생각하는 것 보다 특수문자의 종류는 훨씬 많았다는 것..
    • countTokens()nextToken()을 사용시에 1씩 감소한다 (남은 토큰 수이기 때문에..)
    • 중간에도 문자열이 수정되어 다른 단계의 조건에 해당하는 내용이 발생할 수 있다. (문제 예제 "abcdefghijklmn.p"가 해당된다.)
      으로 생각한다.
      "=.=""abcdefghijklmn.p"을 해결하기 위해 전체 로직에 반복문을 걸어, 로직을 한 번 더 수행시켰다. 덕분에 시간은 더욱 소모되지만, 단계별로 진행하면서 놓친 단계를 한 번 더 점검해준다.

    모범 답안

    class Solution {
        public String solution(String new_id) {
            String answer = "";
            String temp = new_id.toLowerCase();
    
            temp = temp.replaceAll("[^-_.a-z0-9]","");
            System.out.println(temp);
            temp = temp.replaceAll("[.]{2,}",".");
            temp = temp.replaceAll("^[.]|[.]$","");
            System.out.println(temp.length());
            if(temp.equals(""))
                temp+="a";
            if(temp.length() >=16){
                temp = temp.substring(0,15);
                temp=temp.replaceAll("^[.]|[.]$","");
            }
            if(temp.length()<=2)
                while(temp.length()<3)
                    temp+=temp.charAt(temp.length()-1);
    
            answer=temp;
            return answer;
        }
    }

    replaceAll() 함수를 이용해서 특수문자를 처리했다. 이 함수를 위해 정규식을 표현했는데, ^는 ~를 제외한 뜻을 갖는다. 즉, -과 _과 . 과 소문자, 숫자를 제외한 문자들은 뒷 매개변수인 ""로 대체한다. 즉, 무시한다는 의미로 정규식이 반영됐다.
    이후에도 무수한 정규식에 의한 문자열 대치가 진행되는데, 정확한 내용은 정규식을 확인바란다.

    이 예시에서도 "abcdefghijklmn.p"같은 예시를 처리하기 위해 중간에 한 번 더 temp=temp.replaceAll("^[.]|[.]$","");를 실행했다.

    replaceAll()을 잘 다루면 해당 문제를 쉽게 풀 수 있지만, 이를 잘 다루려면 정규식에 대한 이해가 우선이 되어야 한다..

Designed by Tistory.