리트코드 알고리즘/리트코드 medium

(간단한 코드)리트코드 155. Min Stack

문학적 딥러닝 2024. 12. 22. 02:28

 

이 문제는 stack에 필요한 기능들을 담고 있는 클래스를 만드는 문제다.

각 기능을 제대로 이해하는 것보다는 파이썬에서 클래스가 어떤 구성으로 이루어지는지 알아보는 방향으로 가겠다.

class MinStack:

    def __init__(self):
        self.stk = []
        self.min_stk = []

    def push(self, val: int) -> None:
        self.stk.append(val)
        
        if not self.min_stk:
            self.min_stk.append(val)
        elif self.min_stk[-1] < val:
            self.min_stk.append(self.min_stk[-1])
        else:
            self.min_stk.append(val)

    def pop(self) -> None:
        self.stk.pop()
        self.min_stk.pop()

    def top(self) -> int:
        return self.stk[-1]

    def getMin(self) -> int:
        return self.min_stk[-1]

 

클래스는 초기에 항상 헷갈리는 부분 중 하나이다. 웹페이지, 딥러닝 모델 등등 어떠한 프로젝트를 진행하면서 만드는 클래서는, 프레임워크를 통해서 누군가가 만들어 놓은 걸 가져오는 형식이 대부분이다보니, 정작 클래스를 어떻게 만들어야 하는지 잘 모르는 경우가 많다.

 

실제로는 그냥 누군가가 만들어 놓은 형식을 가져와서(상속 시켜서), 그에 맞춰서 짜는게 대부분이다 보니, 굳이 이를 공부해야 한다는 생각을 안하는 사람도 많다.

 

만약에 이미 하고 싶은 프로젝트가 정해져 있고, 응용하는데 큰 문제가 없다고 생각이 들면, 나중에 파도 된다고 생각을 한다. 나는 그저 하고 싶은 프로젝트를 정하지 못해서, 기본기를 다지고 있기만 하고 있을 뿐이다.

클래스는 함수와 어떤 차이가 있을까?

간단하게 설명을 하자면, 함수는 하나의 기능을 수행 할 수 있고, 클래스는 여러개의 함수를 담을 수 있는게 가장 큰 활용도 아닐까 싶다.

 

클래스에서 맨날 헷갈리는 것들은 self, __init__() 이 두 가지 일 것이다.

우선 __init__의 이 아래 선 __init__ 이 선이 의미하는 것을 "절대로 바뀌지 않는다"라는 일종의 "보호"역할을 하는 것이다.

 

이를 설명하는 곳은 많지 않다. 이유는 간단하다, 그냥 외우는게 더 쉽기 때문이고, 실제로 활용하는 곳은 몇 군데로 한정되어 있고, 아래 언더바(_)는 파이썬에서, 이 부분의 "보안성 중요도"를 강조하는 것인데, 실제로 보안은 이렇게 파이썬 언어 보다는 다른 것을 활용하는 것이 더 많기 때문에(활용성이 떨어지기 떄문이 아닐까 싶다) 잘 안쓴다. 

 

이를 실무에서는 다른 것을 상속시키므로 super() __init__(): 어쩌구를 쓰게 될텐데, 여기서 super을 "슈퍼 = 울트라 짱짱 어쩌구"로 생각하기 쉽지만, 실제로는 "superior"이라는 단어의 약자로 "상위 클래스"를 가리킨다. 단어 뜻 만 알아도 대강 왜 있는지 알 수 있다(근데 대부분의 사람들은 단어의 뜻을 설명할 생각을 못하는 것인지, 아니면 그냥 본인들도 모르는 것인지 잘 모르겠다).

 

클래스에 대해 여러가지 비유를 통해 설명하는 곳은 많지만, 정작 본인이 클래스를 활용하다가 대강 이해를 하는게 아닌 이상, 비유 설명만으로 이를 제대로 이해하기는 쉽지 않았다. 

 

두번째로 self는 "클래스 내부에 있을 경우"에만 사용된다. 항상 나오는 말이 "self는 객체 자기 자신"이라는 말을 한다.

이게 무슨 소리인지, 설명을 들어도 헷갈리고, 잘 이해가 안간다. 개념 자체는 쉽다고 할 수 있는데, 정작 사용하려니 헷갈리는 부분이 많다.

import torch
import matplotlib.pyplot as plt

class SimpleNN(torch.nn.Module): #torch라는 라이브러리에 있는 구조를 상속
  def __init__(self, d, w, D, activation=torch.sigmoid):
    super().__init__() #상속 받은 우리 눈에는 보이지 않는 여러 기능을 사용하겠다는 것
    self.fc1 = torch.nn.Linear(d, w)
    self.fc2 = torch.nn.Linear(w, D)
    self.activation = activation

  def forward(self, x): #여기서 x는 우리가 저장할 녀석이 아니어서, self가 안 붙는다
    x = self.fc1(x)
    x = self.activation(x)
    x = self.fc2(x)
    return x

 

이 코드는 딥러닝에서 기본 ANN이라고 기본 신경망을 짠 코드이다. 솔직히 이게 뭔지 이론을 공부한 사람들도 코드를 보면 "이게 뭐징?"하는 사람들이 많다. 

 

이 코드를 보여준 이유는, self는 __init__()안에 들어 있는 변수에만 할당 되고, 그 외의 같은 클래스 안에 있지만 다른 함수(여기서는 forward)에 있는 변수(x)는 self가 붙지 않는다라는 것만 알아도, 앵간하면 문제가 없을 것이다.