백준 강력한 비밀번호

KIMYEONGJUN·2025년 11월 29일
post-thumbnail

문제

내가 생각했을때 문제에서 원하는부분

첫째 줄에 문자열의 길이 N(1 ≤ N ≤ 100), 둘째 줄에 문자열 S가 주어진다.
S는 알파벳 소문자, 대문자, 특수문자(!@#$%^&*()-+), 숫자로만 이루어져 있다.

첫째 줄에 리듬 테트리스의 비밀번호 규칙을 지키기 위해 추가해야 하는 문자의 최소 개수를 출력한다.

내가 이 문제를 보고 생각해본 부분

isSpecialChar 헬퍼 메서드:
isSpecialChar(char c): 주어진 문자 c가 문제에서 정의한 특수문자인지 확인하는 정적(static) 메서드이다.
HashSet<Character> specialChars = new HashSet<>();: 특수문자들을 담을 HashSet을 생성한다. 
HashSet은 중복을 허용하지 않고 빠른 탐색이 가능하다.
String specialStr = "!@#$%^&*()-+";: 문제에서 허용하는 특수문자들을 문자열로 정의한다.
for(char sc : specialStr.toCharArray()) { specialChars.add(sc); }: specialStr 문자열을 문자 배열로 변환하여 각 문자를 specialChars 세트에 추가한다.
return specialChars.contains(c);: 입력 문자 c가 specialChars 세트에 포함되어 있다면 true를 반환하고, 아니면 false를 반환한다.
public static void main(String[] args) throws IOException: 자바 프로그램의 시작점이다. 
throws IOException은 입출력 작업 중 발생할 수 있는 예외를 처리하기 위함이다.
int N = Integer.parseInt(br.readLine());: 첫 번째 줄에서 비밀번호의 길이 N을 읽어와 정수로 변환한다.
String S = br.readLine();: 두 번째 줄에서 비밀번호 문자열 S를 읽어온다.
hasLower, hasUpper, hasDigit, hasSpecial: 각각 소문자, 대문자, 숫자, 특수문자 포함 여부를 추적하기 위한 boolean 변수들이다. 
초기값은 모두 false로 설정된다.
for(char c : S.toCharArray()): S 문자열을 문자(char) 배열로 변환하여 각 문자에 대해 반복한다.
Character.isLowerCase(c): 문자가 소문자인지 확인한다.
Character.isUpperCase(c): 문자가 대문자인지 확인한다.
Character.isDigit(c): 문자가 숫자인지 확인한다.
isSpecialChar(c): 위에서 정의한 헬퍼 메서드를 사용하여 문자가 특수문자인지 확인한다.
각 조건이 만족되면 해당 boolean 변수를 true로 설정한다. 
한 번 true가 되면 다시 false로 바뀌지 않으므로, 문자열에 해당 유형의 문자가 하나라도 있으면 true가 유지된다.
neededTypes: 현재 S가 만족하지 못한 문자 유형의 개수를 세는 변수이다.
각 boolean 변수가 false(!)이면, 해당 유형의 문자가 부족하다는 의미이므로 neededTypes를 1 증가시킨다.
neededLength: 현재 S의 길이가 6보다 작을 때, 6글자를 만들기 위해 필요한 글자 수를 계산합니다. N이 6 이상이면 0이다.
Math.max(neededTypes, neededLength): neededTypes와 neededLength 중 더 큰 값을 최종 결과로 선택하고 출력한다. 
위에서 설명했듯이, 추가하는 문자 하나는 유형 조건과 길이 조건에 동시에 기여하기 때문이다.
br.close();: BufferedReader는 시스템 자원을 사용하므로, 사용 후에는 반드시 닫아주어 자원 누수를 방지한다.

코드로 구현

package baekjoon.baekjoon_31;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;

// 백준 16944번 문제
public class Main1221 {
    // 특수 문자인지 확인하는 헬퍼 메서드
    private static boolean isSpecialChar(char c) {
        // 문제에서 주어진 특수문자 집합: !@#$%^&*()-+
        Set<Character> specialChars = new HashSet<>();
        String specialStr = "!@#$%^&*()-+";
        for(char sc : specialStr.toCharArray()) {
            specialChars.add(sc);
        }
        return specialChars.contains(c);
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());
        String S = br.readLine();

        // 4가지 조건 (소문자, 대문자, 숫자, 특수문자) 만족 여부
        boolean hasLower = false;
        boolean hasUpper = false;
        boolean hasDigit = false;
        boolean hasSpecial = false;

        for(char c : S.toCharArray()) {
            if(Character.isLowerCase(c)) {
                hasLower = true;
            } else if(Character.isUpperCase(c)) {
                hasUpper = true;
            } else if(Character.isDigit(c)) {
                hasDigit = true;
            } else if(isSpecialChar(c)) {
                hasSpecial = true;
            }
        }

        // 4가지 조건 중 만족하지 못한 개수 계산
        int neededTypes = 0;
        if(!hasLower) {
            neededTypes++;
        }
        if(!hasUpper) {
            neededTypes++;
        }
        if(!hasDigit) {
            neededTypes++;
        }
        if(!hasSpecial) {
            neededTypes++;
        }

        // 최소 길이(6)를 만족하기 위해 필요한 개수 계산
        int neededLength = 0;
        if(N < 6) {
            neededLength = 6 - N;
        }

        // 필요한 문자 유형 개수와 길이 부족분 중 더 큰 값을 결과로 출력
        // 추가되는 문자는 유형을 만족시킴과 동시에 길이를 늘리는 데 기여하기 때문입니다.
        System.out.println(Math.max(neededTypes, neededLength));
        br.close();
    }
}

마무리

코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.

profile
Junior backend developer

0개의 댓글