[PS] BOJ 19844 / 단어 개수 세기

[PS] BOJ 19844 / 단어 개수 세기
문제 링크: https://www.acmicpc.net/problem/19844
Thumbnail: Photo by Sven Brandsma (Unsplash)

문제 조건대로 구현하는게 간단할 거라 생각했지만, 생각보다 디테일에서 고전했습니다...

풀이

문제에서 이야기한 단어를 구분하는 조건은 다음과 같습니다:

  • 기본적으로는 띄어쓰기나 -(하이픈) 단위로 단어를 구분한다.
  • 앞 단어가 cejenemeteseleladeque 혹은 si이고 뒤 단어가 모음(aeiouh)으로 시작하는 경우, 앞 단어의 마지막 모음이 사라지고, 대신 '(어포스트로피)가 붙으면서 이어진다.
    • 프랑스어에서 h는 언제나 묵음이므로, 이 문제에서는 일반적으로 알려진 모음 a, e, i, o, u는 물론이고 h도 모음으로 취급함에 유의하라.

그렇다면, 문제를 풀기 위해 해야 하는 작업은 다음과 같습니다:

  • 띄어쓰기 및 -(하이픈) 단위로 문자열을 쪼개 단어의 배열을 만듭니다. 이를 words라고 부르겠습니다.
  • words의 각 단어를 순회하며, 아래 동작을 수행합니다:
    • 만약 '가 들어있다면:
      • 문자열을 '를 기준으로 1회 분할합니다. 분할한 결과를 앞에서부터 f, b라고 부르겠습니다.
      • f(c, j, n, m, t, s, k, d, qu) 중에 있고, b[0] 가 모음 (a, e, i, o, u) 이라면 단어의 개수를 2개로, 그렇지 않다면 1개로 계산합니다.
    • 그렇지 않다면 단어의 개수를 1개로 계산합니다.
  • words를 순회하며 센 단어의 개수의 합을 출력합니다.

전체 코드

input = open(0).readline
text = input().strip()
front = ("c", "j", "n", "m", "t", "s", "l", "d", "qu")
back = ("a", "e", "i", "o", "u", "h")

words = text.replace("-", " ").split()
cnt = 0
for w in words:
    if "'" in w:
        f, b = w.split("'", 1)
        if f in front and b[0] in back:
            cnt += 2
        else:
            cnt += 1
    else:
        cnt += 1
print(cnt)

solution.py

시행착오

str.split(delimeter) 의 경우, 매개변수로 입력한 delimeter 문자로 기존 문자열을 분할합니다. 하지만, 이 경우 a'b'c'd 같은 입력이 와버리면 그대로 4개로 문자를 쪼개는 동작이 되고, 문제에서는 처음 '를 제외한 나머지 부분은 쪼갤 필요가 없으므로 불필요한 동작이 됩니다.

질문 게시판을 구경하던 도중, 좋은 답변을 발견해 str.split()에 대한 새로운 사실을 배웠습니다. str.split(delimeter, times) 꼴로 2번째 매개변수를 주게 되면, times 만큼만 앞에서부터 문자열을 분리합니다. 예를 들면 다음과 같습니다.

>>> "a_b_c_d".split("_", 0)
['a_b_c_d']
>>> "a_b_c_d".split("_", 1)
['a', 'b_c_d']
>>> "a_b_c_d".split("_", 2)
['a', 'b', 'c_d']
>>> "a_b_c_d".split("_", 3)
['a', 'b', 'c', 'd']
>>> "a_b_c_d".split("_", 4)
['a', 'b', 'c', 'd']