본문 바로가기
Python 코딩도장

파이썬 코딩도장 Unit 28 정리(1) - 회문 판별하기

by chanfficial 2022. 2. 17.

Unit 28. 회문 판별과 N-gram 만들기

 

1. 회문 판별하기

  • 회문(palindrome)은 순서를 거꾸로 읽어도 제대로 읽은 것과 같은 단어와 문장을 말한다.(ex : level, SOS, rotator)
  • 첫 번째 글자와 마지막 글자가 같고, 안쪽으로 한 글자씩 좁혔을 때 글자가 서로 같으면 회문이다.
    가운데 문자 v를 기준으로 왼쪽과 오른쪽이 같음

 

1-1. 반복문으로 문자 검사하기

  • 반복문으로 문자열의 각 문자를 검사할 때, 문자열 'level'은 회문이므로 True가 출력되고 회문이 아닌 단어들을 입력하면 False가 출력된다.
    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​
  • 회문 판별은 문자열의 길이를 기준으로 하기 때문에, 회문 판별에서 가장 중요한 부분은 문자열(단어)의 길이이다.(즉, 문자열을 절반으로 나누어서 왼쪽 문자와 오른쪽 문자가 같은지 검사해야함)
  • 반복을 할 때는 문자열 길이의 절반만큼만 반복하도록 한다. ex) 문자열의 길이가 5라면 5 // 2 = 2(버림 나눗셈)이므로 가운데 글자 바로 앞까지만 검사하게 된다.
    for i in range(len(word) // 2):      # 0부터 문자열 길이의 절반만큼 반복​
  • 반복문 안에서는 왼쪽 문자 word[i]와 오른쪽 문자 word[-1-i]를 비교하여 문자가 다르면 회문이 아니므로 is_palindrome에 False를 넣어주고 break로 반복문을 끝내며, 어차피 회문이 아니므로 더 검사할 필요가 없다.
        if word[i] != word[-1 - i]:      # 왼쪽 문자와 오른쪽 문자를 비교하여 문자가 다르면
            is_palindrome = False        # 회문이 아님
            break​
  • for 반복문의 i가 0부터 1씩 증가하므로 word[i]는 왼쪽에서 오른쪽으로 진행하고, word[-1-i]는 오른쪽에서 왼쪽으로 진행한다.
  • 즉, 문자열의 마지막 문자는 word[-1]이므로 여기서 인덱스를 i만큼 계속 빼주면 오른쪽에서 왼쪽으로 진행한다.
    • 이 부분은 파이썬에서 음수 인덱스를 지정하면 뒤에서부터 요소에 접근할 수 있다는 점을 이용한 것이다.
    • 음수 -1에서 숫자를 빼면 -2, -3, -4 처럼 되므로 i가 커질 수록 더 왼쪽으로 온다.
      회문 판별 과정
    • 참고로 word[-1-i]는 word[-(1+i)]와 같이 숫자를 i만큼 증가시킨 뒤 음수로 바꾸는 방식으로도 표현할 수 있다.

 

 

 

1-2. 시퀀스 뒤집기로 문자 검사하기

  • 회문은 시퀀스 객체의 슬라이스를 활용하여 간단하게 판별할 수 있다
    word = input('단어를 입력하세요: ')
     
    print(word == word[::-1])    # 원래 문자열과 반대로 뒤집은 문자열을 비교
    
    # 실행 결과
    단어를 입력하세요: level (입력)
    True
    단어를 입력하세요: hello (입력)
    False​
    - word[::-1]은 문자열 전체에서 인덱스를 1씩 감소시키면서 요소를 가져오므로 문자열을 반대로 뒤집는다.

 

 

 

1-3. 리스트와 reversed 사용하기

  • 반복 가능한 객체의 요소 순서를 반대로 뒤집는 reversed를 통해서도 회문을 판별할 수 있다.
    >>> word = 'level'
    >>> list(word) == list(reversed(word))
    True​
  • list에 문자열을 넣으면 문자 하나 하나가 리스트의 요소로 들어가는데, 여기서 reversed로 문자열을 반대로 뒤집은 다음 list에 넣으면 문자 순서가 반대로 된 리스트를 구할 수 있다.
    >>> list(word)
    ['l', 'e', 'v', 'e', 'l']
    >>> list(reversed(word))
    ['l', 'e', 'v', 'e', 'l']​
  • 이 두 리스트를 ==로 비교하면 문자열이 회문인지 판별할 수 있다.

 

 

 

1-4. 문자열의 join 메서드와 reversed 사용하기

  • 문자열의 join 메서드를 사용해서 회문을 판별할수도 있다.
    >>> word = 'level'
    >>> word == ''.join(reversed(word))
    True​
  • join은 구분자 문자열과 문자열 리스트의 요소를 연결한다.
  • 여기서는 빈 문자열 ' '에 reversed(word)의 요소를 연결했으므로 문자 순서가 반대로 된 문자열을 얻을 수 있다.
  • 즉, join은 요소 사이에 구문자를 넣지만 빈 문자열 ' '을 활용하여 각 문자를 그대로 연결하는 방식이다.
    >>> word
    'level'
    >>> ''.join(reversed(word))
    'level'​
  • 이 두 문자열을 ==로 비교하면 문자열이 회문인지 판별할 수 있다.