백준 문제 풀이

[0일차](문제 번호 : 2941, 크로아티아 알파벳) 도전

danmuji1000 2023. 7. 17. 04:12

바로 풀이에 들어가기에 앞서, 0일 차로써 이 문제를 푸는 이유는 풀고 있던 문제이기 때문에, 1일 차로써 선정하기 별로였기에 이 문제를 0일 차 문제로써 선정했다.

 

 1. 문제 요약

위 표에 나와있는 것처럼 크로아티아 알파벳을 일반적으로 입력가능한 알파벳으로 변경해 그 내용을 저장했다.

이때, 입력된 문장은 총 몇 글자인지 세는 것이 목적이다.

(단, 위에 없는 알파벳은 하나로 세며, nj를 n과 j로 보는 것이 아닌 무조건 nj로 (1개로) 센다.)

 


예시.

입력 :

ljes=njak

출력:

6

2. 풀어보기

이 문제의 핵심은 크로아티아 알파벳은 끝이 - 또는 = 또는 j로 끝난다는 것이다.

따라서, 문장을 입력받은 후, 문장을 뒤집고, 그 뒤집은 문장을 앞에서부터 한 글자씩 읽는다.

그 글자가 - 또는 = 또는 j 일 경우, 뒷글자를 조사해본다. 크로아티아 알파벳이 맞을 경우 총글자에서 1글자 또는 2글자를 뺀다.


1차 시도.

snt = input()
rev_snt = snt[::-1]
length = len(snt)
count = 0
for i in range(length):
    if rev_snt[i] == '=':
        if rev_snt[i+1] == 'c':
            count += 1
        elif rev_snt[i+1] == 'z':
            try:
                if rev_snt[i+2] == 'd':
                    count += 2
                else:
                    count += 1
            except:
                break
        else:
            count += 1
    elif rev_snt[i] == '-':
        count += 1
    elif rev_snt[i] == 'j':
        try:
            if rev_snt[i+1] == 'n' or rev_snt[i+1] == 'l':
                count += 1
        except:
            break
trans = length - count
print(trans)

 

백준에서 제공한 보여지는 예시들은 모두 통과를 했지만, 채점을 한 결과 틀렸다.

무엇이 문제일까..?


 

3. 문제점

 

수많은 예시를 돌려 확인해 본 결과, snt == 'z=' 일 때, 출력값이 2인 것을 확인했다.

아래의 첫 번째 try 문에서 실수가 있었음을 알게 되었다.

            try:
                if rev_snt[i+2] == 'd':
                    count += 2
                else:
                    count += 1
            except:
                break

 

rev_snt[2]는 존재하지 않으므로 except문이 실행되고 count 가 1 증가하지 않은 채 break 된다.

except 부분에 count +=1 을 추가하여 제출해 정답을 맞혔다.


4. 최종 코드

snt = input()
rev_snt = snt[::-1]
length = len(snt)
count = 0
for i in range(length):
    if rev_snt[i] == '=':
        if rev_snt[i+1] == 'c':
            count += 1
        elif rev_snt[i+1] == 'z':
            try:
                if rev_snt[i+2] == 'd':
                    count += 2
                else:
                    count += 1
            except:
                count += 1
                break
        else:
            count += 1
    elif rev_snt[i] == '-':
        count += 1
    elif rev_snt[i] == 'j':
        try:
            if rev_snt[i+1] == 'n' or rev_snt[i+1] == 'l':
                count += 1
        except:
            break
trans = length - count
print(trans)


5. 개선방안

나의 코드를 제출한 후, 다른 정답 코드를 몇 살펴보았다.

비교해 보니 나의 코드가 다른 코드에 비해 너무 긴 것임을 알아챘다.

나는 중첩 if문을 활용하여 코드의 길이가 길어진 것에 반해,

다른 정답 코드들은 위 표의 특정한 크로아티아 알파벳을 리스트로 묶어 replace 함수를 활용하여 한 글자로 압축시켜 문장

을 재구성한 후, 글자 수를 세는 식을 이용하였다.

이번 문제에서 두 가지 몰랐던 점을 얻어가는 것 같아 좋다.


6. 얻어가는 것

1. replace 함수

list.replace(old, new, count)

old -> new로 count 번 바꿈.

 

2. try-except 문 안에서의 if 문 활용법