본문 바로가기

Dot Algo∙ DS/PS

[프로그래머스] 2021 카카오/ 신규 아이디 추천 (Java)

    #1 신규 아이디 추천

    2021 카카오 블라인드

    난이도 : LEVEL 1

    유형 : 문자열 / 정규식

     

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

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

    programmers.co.kr

    [문제]

    신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, "네오"가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요.

     

    [제한사항]

    new_id는 길이 1 이상 1,000 이하인 문자열입니다.
    new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있습니다.
    new_id에 나타날 수 있는 특수문자는 -_.~!@#$%^&*()=+[{]}:?,<>/ 로 한정됩니다.

     

    문제 풀이   

    1단계. new_id의 모든 대문자를 대응되는 소문자로 치환합니다.


    2단계. new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.


    3단계.new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.


    4단계. new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.


    5단계. new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.


    6단계. new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다. 만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.


    7단계. new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.

     

    해당 문제는 위의 7단계를 차례대로 풀어나가면 되므로 따로 풀이과정이라고 할 것은 없다.

     

    1차 풀이 코드는 생각나는 대로 써내려가서 금방 풀었고,

    2차 풀이 코드는 다른 코드들도 참고하여 깔끔하게(replaceAll) 가공하였다.

     

    자바 정규식 참고

     

    1차 풀이 코드 

    // blind #1 신규 아이디 추천
    // 정규식, 문자열  (replaceAll 사용해서 다시 풀어보기) 
    import java.util.*;
    import java.util.regex.Pattern;
    
    public class RecommendNewId {
    
    	static List<String> spec = new ArrayList<>();
    	public static void main(String[] args) {
    //		String new_id = "...!@BaT#*..y.abcdefgh.jk lm";
    		String new_id = "=.=";
    
    		System.out.println(solution(new_id));
    	}
    
        public static String solution(String new_id) {
    
            // 1단계 
            String[] a = new_id.toLowerCase().split("");
    
            List<String> list = new LinkedList<>();	
    
            for(String s : a) {
    //        	System.out.println(s);
            	list.add(s);
            }
    
            spec = new ArrayList<>();
            spec.add("-");
            spec.add("_");
            spec.add(".");
            spec.add(" ");
    
    
            // 2단계 
    //        int size = list.size();
            for(int i=0; i<list.size(); i++) {
            	String s = list.get(i);
            	if(!spec.contains(s) && !Pattern.matches("[a-z0-9]", s)) {
            		list.remove(i);
            		i--;
    //        		size = list.size();
            	}
            }
    
    
            // 3단계 
            for(int i=1; i<list.size(); i++) {
            	String s = list.get(i);
            	if(s.equals(".") && s.equals(list.get(i-1))) {
            		list.remove(i);
            		i--;
            	}
            }
    
    
            // 4단계 
            dotCheck(list);
    
            // 5단계 
            if(list.size() ==0 || list.contains(" ")) {
            	for(int i=0; i<list.size(); i++) {
            		if(list.get(i).equals(" ")) {
            			list.set(i, "a");
            		}
            	}
    
            	if(list.size()==0) list.add("a");
            }
    
    
            for(int i=0; i<list.size(); i++) {
              	String s = list.get(i);
              	System.out.print(s);
               }
                System.out.println();
    
    
          // 6단계 
          while(list.size() > 15) {
        	  list.remove(15);
          }
          dotCheck(list);
    
    
    //      for(int i=0; i<list.size(); i++) {
    //      	String s = list.get(i);
    //      	System.out.print(s);
    //       }
    
          // 7단계 
          if(list.size() <3) {    	  
        	  String s = list.get(list.size()-1);
        	  while(true) {
        		  if(list.size() >= 3) break;
        		  list.add(s);
        	  }
          }
    
          StringBuilder sb = new StringBuilder();
          for(String s : list) {
        	  sb.append(s);
          }
    
            return sb.toString();
    
        }
    
        static void dotCheck(List<String> list) {
        	if(list.get(0).equals(".")) list.remove(0);
    
        	if(list.size()>0 && list.get(list.size()-1).equals(".")) list.remove(list.size()-1);
        }
    }

     

    2차 풀이 코드 

    효율성은 두개가 그닥 차이가 나지 않지만 가벼운 연산은 1번이 살짝 더 효율적이다.

    그러나 코드 작성에서는 replaceAll이 훨씬 편하다.

    // blind #1 신규 아이디 추천
    // 정규식, 문자열  (replaceAll)
    // 효율성은 두개가 그닥 차이가 나지 않는다 
    // 그러나 가벼운 연산은 1번이 살짝 더 효율적인듯 하지 코드 작성쪽에서는 replaceAll이 훨씬 편하다   
    
    public class RecommendNewId2 {
    
    	public static void main(String[] args) {
    		String new_id = "abcdefghijklmn.p";
    //		String new_id = "=.=";
    
    		System.out.println(solution(new_id));
    	}
    
        public static String solution(String new_id) {
    
        	String tmp = new_id.toLowerCase();
    
        	System.out.println(tmp);
    
    
        	// 2단계 
        	tmp = tmp.replaceAll("[^-_.a-z0-9]", "");
        	System.out.println(tmp);
    
        	// 3단계 
        	tmp = tmp.replaceAll("[.]{2,}", ".");
        	System.out.println(tmp);
    
        	// 4단계 
        	tmp = tmp.replaceAll("^[.]|[.]$", "");
        	System.out.println(tmp);
    
    
        	// 5단계 
        	if(tmp.equals("")) tmp += "a";
        	if(tmp.length() > 15) {
        		tmp = tmp.substring(0,15);
        		tmp = tmp.replaceAll("^[.]|[.]$", "");
        	}
        	System.out.println(tmp);
    
    
        	if(tmp.length()<3) {
        		while(tmp.length()<3) {
        			tmp += tmp.charAt(tmp.length()-1);
        		}
        	}
        	System.out.println(tmp);
    
        	return tmp;
    
        }
    
    }