신규 아이디 추천 (자바 Java) : [프로그래머스 코딩테스트 연습 - Level 1]

daehong770·2021년 11월 19일
2
post-thumbnail

1. Problem (문제) 📖

(1). 문제 설명 📖

【 신규 아이디 추천 (카카오 문제) 】
  https://programmers.co.kr/learn/courses/30/lessons/72410


(2). 제한사항 📖


(3). 입출력 예 📖



2. Solution Approach (풀이 접근) 🔑

  • 지정된 7가지 규칙을 순서대로 이행하는 코드를 구현해야 한다.

  • 정규표현식을 활용하면 쉽게 접근할 수 있다. (필자는 첫 풀이때 정규식을 몰랐음)
  • 메인함수와 Sout등으로 디버깅을 해보며 풀어본다.


3. Code (코드) 💻

(1). 내가 처음 작성한 코드 💻

  class Problem_002_MySolution001 {
	public String solution(String new_id) {
		
		int length = new_id.length();	// 글자수
		String tempAnswer = "";		// 중간 테스트 String
		String tempAnswer2 = "";	// 중간 테스트 String 2
		
		// 1단계 (대문자 → 소문자)
		for (int i=0; i<length; i++) {
			if (Character.isUpperCase(new_id.charAt(i))) {
				int temp = (int)new_id.charAt(i) + 32;
				tempAnswer += (char)temp;
			} else {
				tempAnswer += new_id.charAt(i);
			}
		}
		System.out.println("1차테스트 : " + tempAnswer);
		
		// 2단계 (소문자, 숫자, -, _, .를 제외한 문자 제거)
		char[] temp = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-' , '_' , '.'};
		for (int i=0; i<length; i++) {
			if (Character.isLowerCase(tempAnswer.charAt(i))) {
				tempAnswer2 += tempAnswer.charAt(i);
			} else {
				for (int j=0; j<temp.length; j++) {
					if (temp[j] == tempAnswer.charAt(i)) {
						tempAnswer2 += tempAnswer.charAt(i);
						break;
					}
				}
			}
		}
		System.out.println("2차테스트 : " + tempAnswer2);
		
		// 3단계 (마침표(.)가 연속으로 2번 찍힌 경우, 1개로 바꿔주기)
		tempAnswer = "";
		for (int i=0; i<tempAnswer2.length()-1; i++) {
			if (tempAnswer2.charAt(i) != tempAnswer2.charAt(i+1)) {
				tempAnswer += tempAnswer2.charAt(i);
			}
			if (i == tempAnswer2.length()-2) {
				tempAnswer += tempAnswer2.charAt(i+1);
			}
		}
		System.out.println("3차테스트 : " + tempAnswer);
		
		
		// 4단계 (마침표(.)가 처음이나 마지막에 있을시 제거)
		tempAnswer2 = "";
		for (int i=0; i<tempAnswer.length(); i++) {
			if (i==0) {
				if (tempAnswer.charAt(0) != '.') {
					tempAnswer2 += tempAnswer.charAt(i);
				} 
			} else if (i==tempAnswer.length()-1) {
				if (tempAnswer.charAt(tempAnswer.length()-1) != '.') {
					tempAnswer2 += tempAnswer.charAt(i);
				} 
			} else {
				tempAnswer2 += tempAnswer.charAt(i);
			}
		}
		System.out.println("4차테스트 : " + tempAnswer2);
		
		// 5단계 (빈문자열이 되면, a를 넣어주기)
		tempAnswer = "";
		if (tempAnswer2 == "") {
			tempAnswer2 = "a";
		}
		tempAnswer = tempAnswer2;
		System.out.println("5차테스트 : " + tempAnswer);
		
		
		
		// 6단계 (ID 길이는 15자까지만)
		tempAnswer2 = "";
		if (tempAnswer.length() > 15) {
			for (int i=0; i<15; i++) {
				tempAnswer2 += tempAnswer.charAt(i);
			}
		} else {
			tempAnswer2 = tempAnswer;
		}
		System.out.println("6차테스트 : " + tempAnswer2);
		
		// 다시 양 끝에 .가 있는지 확인
		tempAnswer = tempAnswer2;
		tempAnswer2 = "";
		for (int i=0; i<tempAnswer.length(); i++) {
			if (i==0) {
				if (tempAnswer.charAt(0) != '.') {
					tempAnswer2 += tempAnswer.charAt(i);
				} 
			} else if (i==tempAnswer.length()-1) {
				if (tempAnswer.charAt(tempAnswer.length()-1) != '.') {
					tempAnswer2 += tempAnswer.charAt(i);
				} 
			} else {
				tempAnswer2 += tempAnswer.charAt(i);
			}
		}
		
		
		
		// 7단계 (2자 이하일 시, 마지막 문자를 추가)
		tempAnswer = "";
		while (true) {
			if (tempAnswer2.length() < 3) {
				tempAnswer2 += tempAnswer2.charAt(tempAnswer2.length()-1);
			} else {
				break;
			}	
		}
		tempAnswer = tempAnswer2;
		System.out.println("7차테스트 : " + tempAnswer);
		
	// 답
        String answer = tempAnswer;
        return answer;
    }
}

👶🏻 이 때 이 문제를 풀 때는 '정규표현식'이라는 개념을 아예 모를때였다. 학원에서 주는 문제풀이만 하다가 프로그래머스라는 바다에 던져지니 모르는 것 투성이었다.

👶🏻 문제풀이 시간은 1시간20분이나 걸렸고, 겨우 테스트문제를 통과하여 '제출'을 눌렀더니 결과는 76.9 / 100.0 였다. 즉 오류코드라는 것이다. 정신없이 작성한 코드를 하나하나 뜯어보았지만 엄두가 나지 않았고, 개발자들의 선생님이나 다름없는 '구글'에 자문을 구해보니 "정규표현식"이라는 것이 존재했다. 그것을 공부하고, 문제를 다시 풀어보았다.



(2). 공부 후 다시 작성한 코드 💻

public class Problem_002_MySolution02 {

	public String solution(String new_id) {
		
        String answer = new_id;
        
        // 1단계
        answer = answer.toLowerCase();
        
        // 2단계
        answer = answer.replaceAll("[^a-z0-9-_.]", "");
        
        // 3단계
        answer = answer.replaceAll("[.]{2,}", ".");
        
        // 4단계
        answer = answer.replaceAll("^[.]{1}", "");
        answer = answer.replaceAll("[.]{1}$", "");
        
        // 5단계
        if (answer.equals("")) answer += "a";
        
        // 6단계
        if (answer.length() >= 16) {
        	answer = answer.substring(0, 15);
        }
        
        // 6단계에서 잘라낸 문자열 맨 끝이 마침표(.)일 경우
        answer = answer.replaceAll("[.]{1}$", "");
        
        // 7단계
        while (answer.length() < 3) {
        	answer += answer.charAt(answer.length()-1);
        }
        
        
        return answer;
        
    }	
	
}

👶🏻 훨씬 코드가 깔끔해졌음을 알 수 있다. 물론 오류도 나지 않았고. 100점으로 통과할 수 있었다.


(3). 다른 사람이 작성한 코드 💻

💬 다른 사람의 풀이를 보니, 내 풀이와 비슷하였다.

💬 물론 새 클래스를 만들어서 하는 등 여러가지 방법으로 시도한 사람들도 있었으나, 정규표현식이라는 것을 알고 접근하니 이 방법이 제일 깔끔하다는 생각이 들었다.



4. Solution (풀이) 🎲

  • 1. toLowerCase()는 대문자를 소문자로 바꿔주는 코드이다. / (1단계)
       (반대로 toUpperCase()는 소문자를 대문자로 바꿔주는 코드이다.)
  • 2. replaceAll("A" , "B");는 해당 문자열에서 A를 B로 치환해주는 코드이다.

  • 3. 정규표현식과 replaceAll을 활용하여 문제를 해결한다. / (2~4단계)
  • 4. 공백이 될 경우 a를 추가시켜준다. / (5단계)
  • 5. length로 남은 ID의 길이를 계산해주고, subsrting을 활용하여 문자를 잘라준다. / (6단계)
       (substring(A, B); 를 활용하는데 A는 해당 인덱스부터를 의미하지만, B는 B를 제외한 인덱스까지를 의미한다.)
  • 6. 그렇게 잘라낸 수의 끝 부분이 마침표(.)일 수 있으니, 4단계를 다시 한 번 해준다.
  • 7. length로 문자열의 길이가 3미만이면, charAt를 활용하여 마지막 문자를 확인하고 추가해준다.
  • 8. 최종적으로 나온 문자열을 return한다.


5. 마무리 😀

- 첫 번째 풀이 시간 : [2021-10-26] 16:50 ~ 18:04 (74분)

- 첫 번째 점수 : 76.9 / 100.0


정규표현식을 배운 후 ...

- 두 번째 풀이 시간 : [2021-11-18] 09:30 ~ 09:55 (25분)

- 두 번째 점수 : 100.0 / 100.0

역시 배움에는 끝이 없다. 하나를 배우면, 새로운 것을 배우고 싶은 욕망이 든다. 그것을 충족시켜주기에 프로그래머스는 너무나도 좋은 사이트이다. 그리고 정규표현식을 공부하기는 하였지만, 다 외우지는 못했다. 다음에는 꼭 다 외워둬야겠다.

profile
하루 하루, 한 줄 한 줄, 성장하는 개발자 (Better_than_Yesterday Coding)

0개의 댓글