프로그래머스 - 신규 아이디 추천 [자바]
문제 링크 : 신규 아이디 추천
코딩테스트 연습 - 신규 아이디 추천
카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로
programmers.co.kr
정답
class Solution {
public String solution(String new_id) {
//1단계 소문자 치환
new_id = new_id.toLowerCase();
//2단계 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 문자를 제거
String temp_id = "";
char[] charArr = new_id.toCharArray();
for(char id : charArr){
if(id >= 'a' && id <= 'z'){
temp_id += String.valueOf(id);
}else if(id >= '0' && id <= '9'){
temp_id += String.valueOf(id);
}else if(id == '-' || id == '_' || id == '.'){
temp_id += String.valueOf(id);
}
}
new_id = temp_id;
System.out.println("점 제거 전 : " + new_id);
//3단계 하나의 마침표로 치환
temp_id = "";
charArr = new_id.toCharArray();
boolean dotFlag = false;
//a..b -> a.b
for(char id : charArr){
if(id != '.'){
temp_id += String.valueOf(id);
dotFlag = false;
}else if(id == '.' && dotFlag == false){
//.이라면 뒤에 .이 안 올때까지 + 안하면 됨 그걸 flag로 구분
temp_id += String.valueOf(id);
dotFlag = true;
}
}
new_id = temp_id;
System.out.println("점 제거 후 : " + new_id);
//4단계 처음과 끝 . 이면 제거
if(new_id.startsWith(".")){
new_id = new_id.substring(1);
System.out.println("시작 점 제거 후 : " + new_id);
}
if(new_id.endsWith(".")){
new_id = new_id.substring(0, new_id.length() - 1);
System.out.println("마지막 점 제거 후 : " + new_id);
}
//5단계 빈 문자열이면 a를 대입
if(new_id.equals("")){
new_id += "a";
}
//6단계 16자 이상이면 15개 이후 삭제 제거후 마지막이 . 이면 제거
if(new_id.length() >= 16){
new_id = new_id.substring(0, 15);
System.out.println("15자리 컷 : " + new_id+ " " + new_id.length());
if(new_id.endsWith(".")){
new_id = new_id.substring(0, 14);
System.out.println("마지막 자리 컷 : " + new_id);
}
}
//7단계 2자 이하이면 마지막 문자를 길이가 3되도록 끝에 붙임
String endStr = "";
if(new_id.length() <= 2){
endStr = new_id.substring(new_id.length() - 1);
while(new_id.length() < 3){
new_id += endStr;
}
}
System.out.println(new_id);
return new_id;
}
}
분석
- 제거하는 것보다 허용된 것을 남기는 것이 더 쉽다.
- 제공된 규칙에 따라서 코딩하였는데 정규식을 활용하는게 더 나아보인다.
참고할 만한 정답
- 정규식을 사용하여 훨씬 깔끔하다.
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;
}
}
정규 표현식(Regular Expressions)
정규 표현식(regex) : 설명
. : 임의의 한 문자(단 \는 넣을 수 없음)
^regex : 문자열의 시작이 regex인지
regex$ : 문자열의 끝이 regex인지
* : 앞 문자가 없을 수도 무한정 많을 수도 있음
+ : 앞 문자가 하나 이상
? : 앞 문자가 없거나 하나 있음
[ ] : 문자의 집합이나 범위를 나타내며 두 문자 사이는 - 기호로 범위를 나타낸다.
([^abc] 처럼 ^로 시작하면 not을 나타낸다.)
[abc] : a,b,c중 1개 인지
[abc][vz] : a,b,c중 문자 1개와 v,z중 문자 1개의 조합인지
[^abc] : a,b,c를 제외한 문자 1개
{ } : 횟수 또는 범위를 나타낸다.
( ) : 소괄호 안의 문자를 하나의 문자로 인식
| : or 연산자로 인식
X|Z : X 또는 Z
\ : 정규 표현식 역슬래쉬(\)는 확장문자
\d를 표현하려면 \\d로 표현해야 한다.
\b : 단어의 경계
\B : 단어가 아닌것에 대한 경계
\A : 입력의 시작 부분
\G : 이전 매치의 끝
\Z : 입력의 끝이지만 종결자가 있는 경우
\z : 입력의 끝
\s : 공백 문자
\S : 공백 문자가 아닌 나머지 문자
\w : 알파벳이나 숫자
\W : 알파벳이나 숫자를 제외한 문자
\d : 숫자 [0-9]와 동일
\D : 숫자를 제외한 모든 문자
(?i) : 앞 부분에 (?!)라는 옵션을 넣어주게 되면 대소문자는 구분하지 않습니다.