ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 파이썬, 자료구조 알고리즘, is_pelindrome code
    Python 2024. 7. 19. 12:33

    자료구조 알고리즘

     

    • array : 파이썬의 리스트. 접근 쉬움, 삽입 어려움.
    • linked list (연결리스트) : 직접 구현. 접근 어려움, 삽입 쉬움.
      Array LInked List
    특정 원소 조회 O(1) O(N)
    중간에 삽입, 삭제 O(N) O(1)
    데이터 추가 데이터 추가 시 모든 공간이 다 차버렸다면 새로운 메모리 공간을 할당받아야 한다 모든 공간이 다 찼어도 맨 뒤의 노드만 동적으로 추가하면 된다.
    정리 데이터에 접근하는 경우가 빈번하다면 Array를 사용하자 삽입과 삭제가 빈번하다면 LinkedList를 사용하는 것이 더 좋다.

     

     

    class 

    class에는 매직 매소드인 __init__ 이 들어가는데 가장 먼저 꼭 실행되고, 얘는 첫번째 파라미터로 항상 self를 받는다. 

    파이썬은 self를 알아서 넣어주기 때문에 우리는 self 다음에 오는걸 순서대로 넣어주면 된다.

     

    class code 예시

    class Person:
        def __init__(self, name):
            self.name = name
    
        def sayhello(self, to):
            print(f"hello {to}, I'm {self.name}")
    
    rtan = Person("rtanny")
    rtan.sayhello("hanghae")

    palindrome 팰린드롬 

     

    펠린드롬이란 우영우, 스위스, 기러기, 토마토, eye, hannah, 121, 1441 처럼, 앞에서 읽든 뒤에서 읽든 똑같은 걸 말한다.

     

    펠린드롬인지 아닌지를 판정하는 함수를 만들어볼까..

     

    def is_penindrome(word) 로 해서 word 문자열이랑 이 문자열을 뒤집은 게 같은지 다른지 보면 된다.

     

    사실 처음에는 문자열의 맨 앞 index[0]이랑  맨 뒤 index[-1] 가 다르면 False, 문자열의 길이 len(word)가 1이면 바로보나 뒤집으나 똑같으니까  True 이러면서.. if문을 줄줄이 사탕처럼 써내려갔다. 

    그리고 print(True, message, sep=', ') 이렇게 한 이유는 꼭 True(또는 False)와 메시지가 ,  를 사이에 두고 한줄에 보이게 하고 싶었다.

    def is_palindrome(word):
        # 하나의 값으로 이루어지면 펠린드롬 성립
        if len(word) == 1:
            message = f"{word}는 하나의 문자열로 이루어져 있습니다. 바로 보나 뒤집어 보나 동일합니다."
            print(True, message, sep=', ')
    
        # 맨 앞과 맨 뒤가 다르면 무조건 False니까
        elif word[0] != word[-1]:
            message = f"입력한 {word}의 맨 앞과 맨 뒤가 다르므로 동일하지 않습니다."
            print(False, message, sep=', ')

     

     

    그러고 나서 문자열 word와 word를 뒤집은 값을 비교하는 코드를 넣어줬다.

     

    슬라이싱을  이용해서 문자열을 뒤집는 방법은 이번에 처음 알았다. 처음엔  revered로 했는데.. 뭔가 자꾸 경고가 떠서... 문자열 뒤집는 방법으로 구글링해보니 슬라이싱을 사용하는 방법이 제일 간단했고, [::-1]이 어떤 원리로 역순으로 바꿔주는건지 궁금해져서 찾아봤다.

     

    기본적인 슬라이싱 문법은 이렇게 된다고 한다.

    sequence[start:stop:step]

     

    start와 stop은 우리가 원래 알았던 인덱스로 시작과 끝점을 나타내주는거고, 아무것도 안써주면 처음부터 끝까지니까 [:] 이렇게 되고, step인덱스를 증가시키는 간격인데 step이 -1 로 설정되면 시퀀스가 역순으로 탐색된다고 한다..

    그래서 [::-1] 근데... 그냥.. 간단하니까 땡땡 -1 로 외워놓기로..

     

    아무튼 그렇게 해서 둘을 비교해주면 된다. 

    # 슬라이싱을 이용하여 문자열 전체를 뒤집기
        reversed_word = word[::-1]
    
        # 원래 글자와 뒤집은 글자가 같으면 True
        if word == reversed_word:
            message = f"입력한 {word}를 뒤집으면, {reversed_word} 동일합니다."
            print(True, message, sep=', ')
    
        # 다르면
        else:
            message = f"입력한 {word}를 뒤집으면, {reversed_word} 동일하지 않습니다."
            print(False, message, sep=', ')
    
    
    is_palindrome("a")
    is_palindrome("123")
    is_palindrome("121")
    is_palindrome("eye")

     

    근데 그렇게 해서 전체코드를 실행해보면 이렇게 중복되서 나온다..

    민준튜터님이 "로직을 다시 생각해봐야 할 것 같아요" 라고 하셨다.

    True, a는 하나의 문자열로 이루어져 있습니다. 바로 보나 뒤집어 보나 동일합니다.
    True, 입력한 a를 뒤집으면, a 동일합니다.
    False, 입력한 123의 맨 앞과 맨 뒤가 다르므로 동일하지 않습니다.
    False, 입력한 123를 뒤집으면, 321 동일하지 않습니다.
    True, 입력한 121를 뒤집으면, 121 동일합니다.
    True, 입력한 eye를 뒤집으면, eye 동일합니다.

     

    생각해보니 길이가 어떻든 맨 앞이랑 맨 뒤가 어떻든 그냥 word랑 word뒤집은게 똑같은지 아닌지만 보면 되는거잖아 하는 생각이 들어 그냥 위를 다 날렸다.

     

    최종 코드

    def is_palindrome(word):
        
        # 슬라이싱을 이용하여 문자열 전체를 뒤집기
        reversed_word = word[::-1]
    
        # 원래 글자와 뒤집은 글자가 같으면 True
        if word == reversed_word:
            message = f"입력한 {word}를 뒤집으면, {reversed_word}로 동일합니다."
            print(True, message, sep=', ')
    
        # 다르면
        else:
            message = f"입력한 {word}를 뒤집으면, {reversed_word} 동일하지 않습니다."
            print(False, message, sep=', ')
    
    
    is_palindrome("a")
    is_palindrome("123")
    is_palindrome("121")
    is_palindrome("eye")

     

    실행해보면 깔끔하게 잘 나옴

    True, 입력한 a를 뒤집으면, a 동일합니다.
    False, 입력한 123를 뒤집으면, 321 동일하지 않습니다.
    True, 입력한 121를 뒤집으면, 121 동일합니다.
    True, 입력한 eye를 뒤집으면, eye 동일합니다.

     

    그리고 함수에 반환할 값이 없으면 return을 꼭 쓰지 않아도 된다고 한다


    알아두면 좋은 간단한 개념들

     

    재귀 함수의 조건

    종료 조건을 넣어줘야 한다.

     

     

    언패킹

    가변 키워드 인자를 넣고 싶을 때 > *args **kwargs

     

     

    lamda 함수는 언제 쓸까?

    한줄로 쓸만한 정도의 간단한 함수인데 한 번 쓰고 안 쓸 일회용 함수에 쓰면 된다. 보통 map(), filter(), sorted() 처럼 함수 안에 인자로 들어가서 쓰인다. 

    lamda 입력값: 수행할 연산

     

    [1,2,3,4] 에서 짝수만 반환하는 예시 코드

    num = [1, 2, 3, 4]
    even_num = filter(lambda x: x % 2 == 0, num)
    print(list(even_num)) # [2, 4]

     

     

    반복문을 제어하는 애들

    • break : 반복문 종료
    • continue : continue이후의 코드는 실행하지 않고 다음 반복을 수행한다.
    • pass : 아무것도 안함 (문법적으로는 필요하지만, 할 일이 없을 때 사용)
    • for-else : 끝까지 반복문을 실행한 이후에 else문 실행 (break를 통해 중간에 종료되는 경우에는 else문 실행 안 함)

    for-else 는 별로 안 쓴다고 함 

     

     

    문자열 변경 메소드 (문자열을 s라고 했을 때)

     

    • s.replace(바꾸고 싶은 문자, 바꿀 문자) 

    예를 들어 s = "a123" 일 때 "123" 으로 바꾸고 싶으면 s.replace(a, "") 하면 a 를 아무것도 없는 공백으로 바꿔준거니까 123이 된다. 

     

     

    • s.strip([chars]) : 앞뒤 공백이나, 앞뒤에 있는 특정 문자 제거

    예를 들어

    s = " hello world " 앞 뒤 공백을 제거하고 싶으면 s.strip() 

    s = "xhello worldxx" 앞 뒤에 있는  x를 제거하고 싶으면  s.strip("x")

     

     

    •  s.split(sep=None, maxssplit = -1) : 공백이나 특정 문자를 기준으로 분리

    예를 들어

    s = "hello world" 이거를 공백을 기준으로 분리하고 싶을 때, s.split() 하면 ['hello', 'world'] 이렇게 분리해서 리스트로 나옴

    s = "hello,world" 이면  s.split(",") 하면  ['hello', 'world']이렇게 나온다.

     

     

Designed by Tistory.