프로그래머스 : 신규 아이디 추천(JAVA)

ANN·2024년 12월 24일

코딩테스트

목록 보기
2/2

프로그래머스 신규 아이디 추천

📢 문제 내용

📢 문제 분석

문자열 문제
-> 문자열 관련 메서드나 정규식 등을 익히기 좋겠다.
-> 문제에 나온 조건을 따라 수행

📢 의사결정

적절한 문자열의 메서드를 선택하여 구현

📢 코드구현

0. 제출해야 하는 문자열 선언

제출해야 하는 문자열 answerStringBuilder로 선언
(처음에는 Deque로 했지만 굳이 그럴 필요가 없었다.)

1. 모든 대문자는 소문자로 치환

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

String temp_id = new_id.toLowerCase();

String.toLowerCase()로 모든 대문자는 소문자로 치환
toLoweCaseString클래스에만 사용

2. 문자열의 전체 문자 검색 && 3. 연속된 . 제거

2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.

StringBuilder answer = new StringBuilder();
for (int i = 0; i < temp_id.length(); i++) {
    char ch = temp_id.charAt(i);
    if ((ch >= 'a' && ch <= 'z') || (ch == '-' || ch == '_' || ch == '.') || (ch >= '0' && ch <= '9')) {
        if (answer.length() != 0 && answer.charAt(answer.length() - 1) == ch && ch == '.') {
            continue;
        }
        answer.append(ch);
    }
}

필요치 않은 문자는 제거(deleteCharAt)
-> 필요한 문자를 answerappend

4. 양 끝의 . 제거

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

if (answer.length() != 0 && answer.charAt(answer.length() - 1) == '.') {
    answer.deleteCharAt(answer.length() - 1);
}

if (answer.length() != 0 && answer.charAt(0) == '.') {
    answer.deleteCharAt(0);
}

StringBuilder가 비어있지 않다면, 양 끝의 문자가 .인지 확인하고 제거
ArrayIndexOutOfBoundsException가 발생할 수 있기 때문에 비어있는지 확인하는 조건을 추가해야 함

5. 빈 문자열이라면, a를 대입

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

if (answer.length() == 0) {
    answer.append('a');
}

6. 길이 제한 && 맨 끝의 . 제거

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

while (answer.length() > 15) {
    answer.deleteCharAt(answer.length() - 1);
}

if (answer.charAt(answer.length() - 1) == '.') {
    answer.deleteCharAt(answer.length() - 1);
}

문자열의 길이가 15자 이상이라면, 길이가 15가 될 때까지, StringBuilder의 가장 마지막 문자 제거(deleteCharAt)하고,
문자열의 맨 끝에 .이 있다면 제거(deleteCharAt)

7. 길이 조정

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

while (answer.length() <= 2) {
    answer.append(answer.charAt(answer.length() - 1));
}

길이가 3자 이상이 될 때까지, 맨 마지막 문자를 append

📢 코드

class Solution {
    public String solution(String new_id) {

        // 0. 제출해야 하는 문자열 선언
        StringBuilder answer = new StringBuilder();

        // 1. 모든 대문자는 소문자로 치환
        String temp_id = new_id.toLowerCase();

        // 2. 문자열의 전체 문자 검색
        // 3. 연속된 `.` 제거
        for (int i = 0; i < temp_id.length(); i++) {
            char ch = temp_id.charAt(i);
            if ((ch >= 'a' && ch <= 'z') || (ch == '-' || ch == '_' || ch == '.') || (ch >= '0' && ch <= '9')) {
                if (answer.length() != 0 && answer.charAt(answer.length() - 1) == ch && ch == '.') {
                    continue;
                }
                answer.append(ch);
            }
        }

        // 4. 양 끝의 `.` 제거
        if (answer.length() != 0 && answer.charAt(answer.length() - 1) == '.') {
            answer.deleteCharAt(answer.length() - 1);
        }

        if (answer.length() != 0 && answer.charAt(0) == '.') {
            answer.deleteCharAt(0);
        }

        // 5. 빈 문자열이라면, `a`를 대입
        if (answer.length() == 0) {
            answer.append('a');
        }

        // 6. 길이 제한 && 맨 끝의 `.` 제거
        while (answer.length() > 15) {
            answer.deleteCharAt(answer.length() - 1);
        }

        if (answer.charAt(answer.length() - 1) == '.') {
            answer.deleteCharAt(answer.length() - 1);
        }

        // 7. 길이 조정
        while (answer.length() <= 2) {
            answer.append(answer.charAt(answer.length() - 1));
        }

        return answer.toString();
    }
}

📢 ETC

쓰인 메서드

String.toLowerCase()

String str = "Hello";
System.out.println(str.toLowerCase()); // 출력: hello

문자열의 모든 문자를 소문자로 변환하여 새로운 문자열을 반환

원래 문자열은 변경되지 않으며, 변환된 결과는 새로운 문자열로 변환(불변성)

StringBuilder.append()

StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb); // 출력: Hello World

문자열, 숫자, 문자 등을 StringBuilder 객체 끝에 추가

원래의 StringBuilder객체가 변경(가변성)
연속적으로 호출하여 효율적으로 문자열 연결
문자열 연결 시 +보다 효율적

StringBuilder.length()

StringBuilder sb = new StringBuilder("Hello");
System.out.println(sb.length()); // 출력: 5

StringBuilder에 저장된 문자열의 길이를 반환

문자열의 변경(추가, 삭제 등)에 따라 값이 동적으로 변환
StringBuilder의 길이는 0

StringBuilder.charAt(i)

StringBuilder sb = new StringBuilder("Hello");
System.out.println(sb.charAt(1)); // 출력: e

StringBuilder에서 특정 위치(인덱스)의 문자를 반환

인덱스는 0부터 시작하며, 유효한 범위 내에 존재(0 <= i < length())
범위를 벗어난 인덱스를 전달하면 StringIndexOutOfBoundsException 발생

StringBuilder.deleteCharAt(i)

StringBuilder sb = new StringBuilder("Hello");
sb.deleteCharAt(1);
System.out.println(sb); // 출력: Hllo

StringBuilder에서 특정 위치(인덱스)의 문자를 제거

제거된 후 문자열은 해당 문자를 제외한 상태로 다시 조정
범위를 벗어난 인덱스를 전달하면 StringIndexOutOfBoundsException 발생

String은 불변성을, StringBuilder는 가변성을 가진다...!

0개의 댓글