2941번: 크로아티아 알파벳 - Python

beaver.zip·2022년 2월 24일
0

baekjoon

목록 보기
32/56

https://www.acmicpc.net/problem/2941

문제

예전에는 운영체제에서 크로아티아 알파벳을 입력할 수가 없었다. 따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다.

예를 들어, ljes=njak은 크로아티아 알파벳 6개(lj, e, š, nj, a, k)로 이루어져 있다. 단어가 주어졌을 때, 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.

dž는 무조건 하나의 알파벳으로 쓰이고, d와 ž가 분리된 것으로 보지 않는다. lj와 nj도 마찬가지이다. 위 목록에 없는 알파벳은 한 글자씩 센다.

입력

첫째 줄에 최대 100글자의 단어가 주어진다. 알파벳 소문자와 '-', '='로만 이루어져 있다.

단어는 크로아티아 알파벳으로 이루어져 있다. 문제 설명의 표에 나와있는 알파벳은 변경된 형태로 입력된다.

출력

입력으로 주어진 단어가 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.


풀이 1

croatia = ['c=', 'c-', 'dz=', 'd-', 'lj', 'nj', 's=', 'z=']
str = input()
cnt = 0

for c in croatia:
    if c in str:
        cnt += str.count(c)
    str = str.replace(c, ' ')
str = str.replace(' ', '')
print(len(str) + cnt)

# 편의상 str을 변수명으로 썼다.

코드 설명:

  1. 크로아티아 알파벳을 저장한 croatia, 문자열을 입력받는 str, 글자 수를 세기 위한 cnt를 선언함.
  2. croatia에서 알파벳 c를 순서대로 하나씩 꺼내어,
    만약 입력받은 문자열 str에 c가 있다면: str에 있는 c의 개수를 cnt에 더함.
  3. cnt에 추가했다면 해당 알파벳 c를 리스트에서 공백으로 바꿈.
  4. 2-3의 과정(for문)이 끝나면 3.에서 추가한 공백을 제거함.
  5. cnt와 남은 문자(일반 알파벳들)의 수를 더하여 출력.

시행착오 1

처음 구상한 방식은 index를 사용하는 것인데,
크로아티아 알파벳 c를 croatia에서 하나씩 꺼내어
입력받은 문자열 str에 들어있는지 확인하다가, 만약 c가 str 안에 있으면
index += len(c)하여 다음 반복때는 str[index:]의 범위에서 찾게 하는 것이다.

from string import ascii_lowercase
croatia = ['c=', 'c-', 'dz=', 'd-', 'lj', 'nj', 's=', 'z='] + list(ascii_lowercase)

str = input() # 편의상 str을 변수명으로 사용했다.
cnt = 0
index = 0

for c in croatia:
	if c in str[index:]:
    	cnt += 1
        index += len(c)
print(cnt)

시도는 좋았다고 생각하지만, 이 풀이에는 오점이 있었다.
str[index:]에서 찾는다고 해도, 단어(str) 중간에 c가 있으면 index가 꼬여버린다.
잘못된 풀이였다.

시행착오 2

난 문제를 풀 때, 구현하기 어려운 부분이 있으면 작은 예시를 만들어 테스트해보고,
예시가 의도에 맞게 동작하는게 성공한다면 이를 풀이에 적용한다.

vowel = ['a', 'e', 'i', 'o', 'u']
str = input() # in: 'ajou university' -> out: 7이 되도록 구현하고 싶다.
cnt = 0

for v in vowel:
	if v in str:
    	cnt += str.count(v)
print(cnt)

# 'ajou university'를 입력하면 7이 나온다. 지렸따
# 의도한대로 나왔으니 이를 풀이에 적용해보자.

시행착오 3

다음으로 구성한 방식은 풀이 1과 같다.

croatia = ['c=', 'c-', 'dz=', 'd-', 'lj', 'nj', 's=', 'z=']
str = input()
cnt = 0

for c in croatia:
	if c in str:
    	str = str.replace(c, '')
        cnt += 1
# print(str, len(str), cnt) - 변수가 어떻게 돌아가는지 파악해보려 했다.
print(len(str)+cnt)

맞다고 생각했는데 기대한 값이 나오지 않았고, 어디서 오류가 났는지 예제와 비교해보니

오류 1: 예제 3 - str에서'lj'가 삭제되면 'nj'가 남음 -> 'n', 'j' 따로 인식되는게 아니라 'nj' 하나로 인식됨.
오류 2: 예제 4 - str에서 'c=' 두 개 모두 삭제됨 -> str이 빈 문자열이 되어버림.

오류 1은 for문 안에서는 ' '으로 두었다가 for문이 끝나면 공백을 제거함으로써 해결하였고,
오류 2는 line 7, 8의 순서를 바꾸고 cnt += str.count(c)로 변경함으로써 해결하였다.

풀이 2 (참고한 풀이)

croatia = ['c=','c-','dz=','d-','lj','nj','s=','z=']
word = input()

for c in croatia:
    word = word.replace(c, '*')
print(len(word))

# 영지공지님(https://ooyoung.tistory.com/74)의 풀이입니다.

훨씬 쉬운 방법이 있었다. if문, cnt가 필요 없고 replace도 한 번만 써도 되는 방법이..

word = word.replace(c, '*')에서
만약 c가 word 안에 없다면 다음 c로 지나가므로 if문이 필요 없고,
c를 *(*이 아니더라도 임의의 한 글자)로 바꾸면 replace를 두 번 쓸 필요도 없다.
이렇게 간단한 풀이가 있었다니..
이런 풀이를 하실 수 있다는게 부러울 따름이다.

배운 점

이 문제를 풀면서, 문제를 해결하는 순서에 대해 배운 것 같다.

  1. 프로그램이 어떤 식으로 돌아가게 만들지 구상한다.
  2. 1에서 구상한 것을 코드로 구현한다.
  3. 구현하는 과정에서 막혔다면, 구현하려는 동작과 비슷한 작은 예시를 만들어 테스트해보고,
    이 예시가 의도에 맞게 동작한다면 이를 문제에 적용한다.
  4. 테스트 케이스 대부분을 만족하는 코드를 구현했다면, 오류가 나는 테스트 케이스에서 오류가 발생하는 원인을 찾아낸다.
  5. 4의 오류를 해결하여 프로그램을 완성한다.

나에겐 정말 어려운 문제였으며, 동시에 많은 걸 배우게 해준 고마운 문제다.
profile
mv blog velog.io/@beaver_zip

0개의 댓글