99클럽 코테 스터디 2일차 TIL [04/01]

[시작]

참여 기간 : 2025/03/31 ~ 2025/04/28

참여 난이도 : 파이썬 / 비기너

⏳ 코테 스터디 진행도 🧱 : [▰▰▰░                                               ] 2/29일 (7%)

본 글에서 다룬 문제 : 백준 10820번

 

 

 

 

[오늘의 문제]

오늘의 문제는 백준 10820번

 

 

[문제 분석]

문자열이 N개가 주어진다.

주어진 문자열에 포함되어 있는 소문자, 대문자, 숫자, 공백의 개수를 구해야 한다.

예제의 입출력을 보고 참고하면 되겠다.

 

 

[의사 코드]

  1. 우선 문자열을 하나만 입력받았다고 생각해 보자
  2. 해당 문자열에서 소문자, 대문자, 숫자, 공백의 개수를 구해야 한다.
  3. 구한 개수를 출력한다.
  4. 위 과정을 N번만큼 반복한다.

 

 

[의사 코드를 실제 코드로 구현]

import sys

for line in sys.stdin:
    line = line.rstrip('\n') 

    lowers, uppers, digits, spaces = 0, 0, 0, 0
    for char in line:
        if char.islower():
            lowers += 1
        elif char.isupper():
            uppers += 1
        elif char.isdigit():
            digits += 1
        elif char.isspace():
            spaces += 1

    print(f"{lowers} {uppers} {digits} {spaces}")

CPH Judge

★ 코드 설명 ★

한 문제 밖에 없어서 자세하게 설명

  • sys 모듈 사용
    • 백준에서는 input()보다 sys.stdin이 안정적이고 빠르다해서 사용
  • for line in sys.stdin:
    • sys.stdin은 입력된 데이터를 줄 단위로 읽어옴
    • 파일 끝까지 모든 줄에 대해 반복문을 실행
    • 줄 수가 미리 주어지지 않았기에 사용
  • line = line.rstrip('\n')
    • 문자열 오른쪽 끝에 있는 개행 문자(\n)만 제거
    • 입력받은 줄은 항상 끝에 \n가 포함되어 있기에 사용
    • 사용하지 않으면 공백의 개수를 세는데 문제가 되었음(+1이 되어버림)
  • for char in line:
    • 현재 줄에 포함된 모든 문자를 하나씩 char라는 변수에 대입하여 반복
    • 각 문자를 검사해서 해당하는 카운터를 증가시키기 위해 사용
    • char 말고 마음에 드는 거 사용해도 무관함. 나는 문자열 입력받는 거라 char이 떠올랐음
  • if char.islower():
    • 현재 문자가 소문자인지 확인
    • lowers += 1로 소문자인 게 확인되면 lowers의 값을 1 증가시킴
    • 대문자, 숫자, 공백도 같은 방식 사용
  • print(f"{lowers} {uppers} {digits} {spaces}")
    • f-string을 사용해서 변수들의 값을 문자열 내에 삽입

 

 

 

[메서드 정리]

▶ 대소문자 관련 메서드

  • .islower()
    • 문자열의 모든 알파벳 문자가 소문자이면 True를 반환
  • .isupper()
    • 문자열의 모든 알파벳 문자가 대문자이면 True를 반환
  • .lower()
    • 문자열의 모든 문자를 소문자로 변환
  • .upper()
    • 문자열의 모든 문자를 대문자로 변환
  • .swapcase()
    • 문자열의 대문자를 소문자로, 소문자를 대문자로 바꿈
  • .istitle()
    • 문자열의 각 단어 첫 글자가 대문자이고 나머지가 소문자인지 검사

 

▶ 숫자 관련 메서드

  • .isdigit()
    • 문자열의 모든 문자가 숫자(0~9)로 구성되어 있으면 True를 반환
  • .isnumeric()
    • 숫자와 숫자로 취급될 수 있는 다른 유니코드 문자(분수, 숫자 기호 등)도 포함해서 검사
  • .isdecimal()
    • 순수하게 0부터 9까지의 십진수만 있는지 검사

 

▶ 알파벳 관련 메서드

  • .isalpha()
    • 문자열의 모든 문자가 알파벳일 때 True를 반환
  • .isalnum()
    • 문자열의 모든 문자가 알파벳 또는 숫자일 때 True를 반환

 

▶ 공백 관련 메서드

  • .isspace()
    • 문자열의 모든 문자가 공백 문자(스페이스, 탭, 개행 등)일 때 True를 반환
  • .isprintable()
    • 문자열의 모든 문자가 출력 가능한 문자(공백 포함)일 때 True를 반환

 

▶ 식별자 관련 메서드 (처음 봄)

  • .isidentifier()
    • 문자열이 파이썬 식별자(변수명 등)로 사용할 수 있는지 검사
# 사용 예시 참고
text = "Hello World 123"

print("islower:", text.islower())       # False, 전체 문자가 소문자가 아님
print("isupper:", text.isupper())       # False, 전체 문자가 대문자가 아님
print("lower():", text.lower())          # "hello world 123"
print("upper():", text.upper())          # "HELLO WORLD 123"
print("istitle:", text.istitle())         # True, 각 단어의 첫 글자는 대문자, 나머지는 소문자
print("isalpha:", text.replace(" ", "").isalpha())  # True, 공백 제거 후 모든 문자가 알파벳
print("isalnum:", text.replace(" ", "").isalnum())  # True, 공백 제거 후 모든 문자가 알파벳 또는 숫자
print("isdigit on '123':", "123".isdigit())         # True
print("isspace on '   ':", "   ".isspace())          # True
print("isidentifier on 'var_1':", "var_1".isidentifier())  # True

 

 

[제출 결과]

 

 

[실수한 부분]

문제를 제대로 읽지 않고 처음 코드를 작성할 때

문자열을 N개 입력받는다고? 그럼 처음 N을 입력받고 문자열을 입력하겠구나! 하고 착각함 ㅎㅎ;

그렇게 제출한 뒤에 '런타임 에러'를 보고 문제를 인지해서 코드에서 해당 부분 수정함

수정하고 제출했으나 틀렸음

 

아까 위에서 코드 설명한 부분에 스쳐 지나갔는데, '공백'의 개수를 세어야 하는데 +1이 계속되어서 출력되었음

원인을 찾아보니 \n(개행)되는 것도 공백으로 카운트해서 생긴 문제였음...

 

.rstrip('\n')을 사용해서 해결했고 제출 결과 정답!

로컬에서 CPH Judge를 돌리고 제출하자....

 

 

▶ .rstrip() 설명

  • .rstrip()
    • 오른쪽 끝에 있는 모든 공백 문자를 제거
  • .rstrip("!")
    • 이런 식으로 인자를 주면 해당 인자에 포함된 문자들만 오른쪽 끝에서 제거
  • 특징
    • 원본 문자열을 직접 수정하지 않고, 결과를 새로운 문자열로 반환
    • 제거 대상 문자를 지정 가능
  • 왼쪽 끝 제거
    • .lstrip()을 사용
  • 양쪽 끝 제거
    • .strip()을 사용

 

 

 

[다른 코드]

백준에서 다른 분이 제출한 코드를 가져와봤다.

import sys

while True:
    line = sys.stdin.readline().rstrip('\n')

    if not line:    # 아무것도 입력되지 않았을 때, 즉 빈 문자열이면 루프를 종료
        break

    l, u, d, s = 0, 0, 0, 0
    for each in line:
        if each.islower():   
            l += 1
        elif each.isupper(): 
            u += 1
        elif each.isdigit(): 
            d += 1
        elif each.isspace(): 
            s += 1

    print(l, u, d, s)

이 분 외에도 while문을 사용한 케이스가 많았다.

나도 생각은 해봤는데 for문으로 충분히 가능할 것 같아서 시도하지는 않았다.

이렇게도 할 수 있구나 하고 보고 넘어가면 될 것 같다.

 

 

 

 

[마무리]

쉽게 풀거라 생각했으나 생각보다 시간을 많이 썼다.

문제 읽는 부분에서 실수, 계산 실수로 인해 시간이 2배는 걸린 것 같다.

어떻게 코드를 작성해야겠다는 생각은 드는데 머리에서 바로 구현이 되지 않아서 좀 답답했다.