본문 바로가기
BASIC

회문 판별과 N-gram 만들기

by 자동매매 2023. 11. 28.

1. 회문( palindrome ) 판별하기

회문(palindrome)은 순서를 거꾸로 읽어도 제대로 읽은 것과 같은 단어와 문장을 말합니다.

예를 들면 "level", "SOS", "rotator", "nurses run"과 같은 단어와 문장이 있지요.

 

1) 반복문으로 문자 검사하기

이제 반복문으로 문자열의 각 문자를 검사해보겠습니다.

palindrome.py

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

 

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

palindrome_slice.py

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

실행 결과

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

word == word[::-1] 한 줄로 간단하게 끝났습니다. 너무 쉽죠? word[::-1]은 문자열 전체에서 인덱스를 1씩 감소시키면서 요소를 가져오므로 문자열을 반대로 뒤집습니다. 회문은 순서를 거꾸로 읽어도 제대로 읽은 것과 같은 문자열이므로 원래 문자열 word와 뒤집은 문자열 word[::-1]이 같으면 회문입니다.

3) 리스트와 reversed 사용하기

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

 

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

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

 

2. N-gram 만들기

N-gram은 문자열에서 N개의 연속된 요소를 추출하는 방법입니다.

만약 'Hello'라는 문자열을 문자(글자) 단위 2-gram으로 추출하면 다음과 같이 됩니다.

He
el
ll
lo

 

1) 반복문으로 N-gram 출력하기

이제 반복문으로 문자 단위 2-gram을 출력해보겠습니다.

2_gram_character.py

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

실행 결과

He
el
ll
lo

 

 

글자 단위 N-gram

2_gram_word.py

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

 

2) zip으로 2-gram 만들기

2_gram_character_zip.py

text = 'hello'
 
two_gram = zip(text, text[1:])
for i in two_gram:
    print(i[0], i[1], sep='')

실행 결과

He
el
ll
lo

zip 함수는 반복 가능한 객체의 각 요소를 튜플로 묶어줍니다.

 

3) zip과 리스트 표현식으로 N-gram 만들기

>>> text = 'hello'
>>> [text[i:] for i in range(3)]
['hello', 'ello', 'llo']

 

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

 

>>> list(zip(*['hello', 'ello', 'llo']))
[('h', 'e', 'l'), ('e', 'l', 'l'), ('l', 'l', 'o')]

이제 3-gram 리스트가 만들어졌습니다. 물론 리스트 표현식을 바로 zip에 넣어주려면 리스트 표현식 앞에 *를 붙이면 됩니다.

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

 

 

[연습문제]

표준 입력으로 정수와 문자열이 각 줄에 입력됩니다. 
입력된 숫자에 해당하는 단어 단위 N-gram을 튜플로 출력하세요(리스트 표현식 사용). 
만약 입력된 문자열의 단어 개수가 입력된 정수 미만이라면 'wrong'을 출력하세요.

n = int(input())
text = input()
words = text.split()       
 
if (len(words) < n ):
    print('wrong')
else:
    n_gram = zip(*[words[i:] for i in range(n)])                               
    for i in n_gram:
        print(i)

 

[입력]
7 
Python is a programming language that lets you work quickly 
[결과]
('Python', 'is', 'a', 'programming', 'language', 'that', 'lets')
('is', 'a', 'programming', 'language', 'that', 'lets', 'you')
('a', 'programming', 'language', 'that', 'lets', 'you', 'work')
('programming', 'language', 'that', 'lets', 'you', 'work', 'quickly')


[입력]
7 
Python is a programming language 
[결과]
wrong

 

[ 연습문제 ]

단어가 줄 단위로 저장된 words.txt 파일이 주어집니다. 
words.txt 파일에서 회문인 단어를 각 줄에 출력하는 프로그램을 만드세요. 
단어를 출력할 때는 등장한 순서대로 출력해야 합니다. 
그리고 파일에서 읽은 단어는 \n이 붙어있으므로 \n을 제외한 뒤 회문인지 판단해야 하며 단어를 출력할 때도 \n이 출력되면 안 됩니다(단어 사이에 줄바꿈이 두 번 일어나면 안 됨).

[ words.txt ]
apache
decal
did
neep
noon
refer
river

with open('words.txt','r') as file:
    L = file.readlines()
    result =[]
    for i in L:
        i = i.strip('\n')
        if list(i) == list(reversed(i)):
            result.append(i)

for i in result:
    print(i)

 

did
noon
refer

'BASIC' 카테고리의 다른 글

제너레이터  (0) 2023.11.28
이터레이터  (0) 2023.11.28
파일 다루기  (2) 2023.11.28
set  (0) 2023.11.27
딕셔너리 응용하기  (1) 2023.11.27

댓글