day 5 회문 판별하기

2 minute read

회문 판별과 N-gram

회문

회문(palindrome)은 순서를 거꾸로 읽어도 제대로 읽은 것과 같은 단어와 문장을 말합니다. 예를 들면 “level”, “SOS”, “rotator”, “nurses run”과 같은 단어와 문장이 있지요.

회문은 유전자 염기서열 분석에서 많이 쓰고, N-gram은 빅 데이터 분석, 검색 엔진에서 많이 쓰입니다. 특히 구글은 책들을 스캔해서 N-gram viewer를 만들었는데 사람들의 언어 패턴을 시대별로 분석하기도 했습니다.

image

반복문으로 문자 검사하기

반복문으로 문자열의 각 문자를 검사 하기

word = input('단어를 입력하세요: ')
 
is_palindrome = True                 # 회문 판별값을 저장할 변수, 초깃값은 True
for i in range(len(word) // 2):      # 0부터 문자열 길이의 절반만큼 반복
    if word[i] != word[-1 - i]:      # 왼쪽 문자와 오른쪽 문자를 비교하여 문자가 다르면
        is_palindrome = False        # 회문이 아님
        break
 
print(is_palindrome)                 # 회문 판별값 출력

실행 결과

단어를 입력하세요: level (입력)
True
단어를 입력하세요: hello (입력)
False

시퀀스 뒤집기로 문자 검사하기

word = input('단어를 입력하세요: ')
 
print(word == word[::-1])    # 원래 문자열과 반대로 뒤집은 문자열을 비교

실행 결과

단어를 입력하세요: level (입력)
True
단어를 입력하세요: hello (입력)
False

리스트와 reversed 사용하기


>>> word = 'level'
>>> list(word) == list(reversed(word))
True

>>> list(word)
['l', 'e', 'v', 'e', 'l']
>>> list(reversed(word))
['l', 'e', 'v', 'e', 'l']

문자열의 join 메서드와 reversed 사용하기

>>> word = 'level'
>>> word == ''.join(reversed(word))
True

>>> word
'level'
>>> ''.join(reversed(word))
'level'

N-gram

N-gram은 문자열에서 N개의 연속된 요소를 추출하는 방법입니다. 만약 ‘Hello’라는 문자열을 문자(글자) 단위 2-gram으로 추출하면 다음과 같이 됩니다.

He
el
ll
lo

반복문으로 N-gram 출력

text = 'Hello'
 
for i in range(len(text) - 1):             # 2-gram이므로 문자열의 끝에서 한 글자 앞까지만 반복함
    print(text[i], text[i + 1], sep='')    # 현재 문자와 그다음 문자 출력
..
..
He
el
ll
lo

단어 n-gram

text = 'this is python script'
words = text.split()                 # 공백을 기준으로 문자열을 분리하여 리스트로 만듦
 
for i in range(len(words) - 1):      # 2-gram이므로 리스트의 마지막에서 요소 한 개 앞까지만 반복함
    print(words[i], words[i + 1])    # 현재 문자열과 그다음 문자열 출력
..
..
this is
is python
python script

zip을 2-gram 만들기

text = 'hello'
 
two_gram = zip(text, text[1:])
for i in two_gram:
    print(i[0], i[1], sep='')
..
..  
He
el
ll
lo

>>> text = 'hello'
>>> list(zip(text, text[1:]))
[('h', 'e'), ('e', 'l'), ('l', 'l'), ('l', 'o')]

단어 2-gram

>>> text = 'this is python script'
>>> words = text.split()
>>> list(zip(words, words[1:]))
[('this', 'is'), ('is', 'python'), ('python', 'script')]

zip과 리스트 표현식으로 N-gram

>>> list(zip(['hello', 'ello', 'llo']))
[('hello',), ('ello',), ('llo',)]

결과를 보면 원하는 3-gram이 아닙니다. 왜 그럴까요? zip은 반복 가능한 객체 여러 개를 콤마로 구분해서 넣어줘야 합니다. 하지만 [‘hello’, ‘ello’, ‘llo’]은 요소가 3개 들어있는 리스트 1개이기 때문입니다.

zip에 리스트의 각 요소를 콤마로 구분해서 넣어주려면 리스트 앞에 *를 붙여야 합니다.

>>> list(zip(*[text[i:] for i in range(3)]))
[('h', 'e', 'l'), ('e', 'l', 'l'), ('l', 'l', 'o')]

리스트에 *를 붙이는 방법은 리스트 언패킹(list unpacking)이라고 합니다.

읽을거리 | N-gram의 활용

4-gram을 쓰면 picked, picks, picking에서 pick만 추출하여 단어의 빈도를 세는데 이용됩니다. 이런 특성 때문에 검색엔진, 빅데이터, 법언어학 분야에서 주로 활용됩니다.

summary

image

image

image

Leave a comment