ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 항해 99 5기 TIL_62
    항해 99 2022. 3. 13. 02:48

    ▶ Today I Learned

     

    <알고리즘>

     

    [신나는 함수 실행]

     

    소요시간: 1시간 40분

    해결여부: 미해결

    https://www.acmicpc.net/problem/9184

    유형: 다이나믹 프로그래밍, 재귀

     

    문제와 똑같이 구현해본 처음의 코드

     

    /*
    if a <= 0 or b <= 0 or c <= 0, then w(a, b, c) returns:
        1
    
    if a > 20 or b > 20 or c > 20, then w(a, b, c) returns:
        w(20, 20, 20)
    
    if a < b and b < c, then w(a, b, c) returns:
        w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)
    
    otherwise it returns:
        w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)
    
    a, b, c가 주어졌을 때, w(a, b, c)
    */
    
    const input = [[1, 1, 1], [2, 2, 2], [10, 4, 6], [50, 50, 50], [-1, 7, 18], [-1, -1, -1]]
    
    for(let i = 0 ; i < input.length - 1 ; i++) {
    
    let answer = []
    const a = input[0][0]
    const b = input[0][1]
    const c = input[0][2]
      
      let result = recursion (a,b,c)
    
      console.log(`w(${a}, ${b}, ${c}) = ` + result)
    }
    
    // 재귀함수
    function recursion (a, b, c) {
    
      if(a <= 0 || b <= 0 || c <= 0) {
    
        return recursion (a,b,c) = 1
      }
      else if (a > 20 || b > 20 || c > 20) {
    
        return recursion (20,20,20)
      }
    
     else if (a < b && b < c) {
    
        return recursion (a, b, c-1) + recursion (a, b-1, c-1) - recursion (a, b-1, c)
        
      } else {
    
      return recursion (a-1, b, c) + recursion (a-1, b-1, c) + recursion (a-1, b, c-1) - recursion (a-1, b-1, c-1)
      } 
    }

    하지만 그랬더니 다음과 같은 에러가 발생했다.

    RangeError: Maximum call stack size exceeded
        at recursion (/home/runner/For-algorithm-studying/index.js:32:20)
        at recursion (/home/runner/For-algorithm-studying/index.js:36:12)
        at recursion (/home/runner/For-algorithm-studying/index.js:36:12)
        at recursion (/home/runner/For-algorithm-studying/index.js:36:12)
        at recursion (/home/runner/For-algorithm-studying/index.js:36:12)
        at recursion (/home/runner/For-algorithm-studying/index.js:36:12)
        at recursion (/home/runner/For-algorithm-studying/index.js:36:12)
        at recursion (/home/runner/For-algorithm-studying/index.js:36:12)
        at recursion (/home/runner/For-algorithm-studying/index.js:36:12)

     

    이는 무한히 실행되는 재귀함수 때문에 call stack이 감당할 수 있는 크기를 초과했다는 뜻이다.

    애초에 문제에서도 저렇게 연산하면 답을 구할 순 있지만 연산이 너무 오래걸린다고 하며 시간 제한을 1초로 두었다.

    시간에 좀 더 신경써보아야 겠다.

    + 2022.3.15 참고로 여기서 연산이 초과하는 이유는     return recursion (a,b,c) = 1 때문이다.

    함수에 결과 값을 대입하는 동시에 리턴할 수 없으며 함수 자체를 a,b,c라는 변수를 써서 다시 실행시키기 때문에 무한루프에서 빠져나올 수 없는 것이다.

     

    풀이들을 참고하니 DP 방식이라고 한다.

    3차원이라 이해가 쉽지 않았지만 내일 다시 한번 살펴보고 이해해보아야겠다.

     

     

    cf) 동적 프로그래밍, 동적 계획법 (Dynamic Programming)

    :  이미 했던 연산이 반복되는 결점을 보완하기 위해서 고안된 개념. 처음 진행되는 연산은 기록해 두고, 이미 진행했던 연산이라면 다시 연산하는 것이 아니라 기록되어 있는 값을 가져옴

    이렇게 동일한 문제를 반복해야 할 경우, 한 번 계산된 결과를 저장해 두었다가 활용하는 방식으로 중복 계산을 줄이는 것을
    메모이제이션(Memoization)이라고 함

    피보나치 수열이 대표적인 예시임

     

    피보나치 수열:

    제2항까지는 1, 제3항부터는 바로 앞의 두 항을 더한 수로 정의되는 수열

    ex) (0), 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89… 

     

    출처:

    https://velog.io/@chelsea/1-%EB%8F%99%EC%A0%81-%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming-DP

     

     

    <CS>

     

    [Promise.all]

     

    여러 개의 프로미스를 동시에 실행시키고 모든 프로미스가 준비될 때까지 기다린 후에 다음 로직을 처리해야 하는 상황이 있다.

     

    Promise.all은 이런 상황에 유용하다. Promise.all은 요소 전체가 프로미스인 배열(엄밀히 따지면 Iterable 객체이지만 대개는 배열임)을 받고 새로운 프로미스를 반환한다. 배열 안의 개별 프로미스들이 모두 처리되면 새로운 프로미스가 이행된다. 각 프로미스의 결괏값을 담은 배열이 새로운 프로미스의 result가 되는 것이다. result 배열의 요소 순서는 Promise.all에 전달되는 프로미스 순서와 상응한다. Promise.all의 첫 번째 프로미스가 가장 늦게 이행되더라도 처리 결과는 result 배열의 첫 번째 요소에 저장된다. Promise.all의 프로미스들 중 하나라도 실패하면 Promise.all은 즉시 거부되고 result 배열에 저장되어있던 다른 프로미스의 결과들도 사라진다. 실패한 에러는 Promise.all의 catch로 넘어간다.

     

    - Promise.all의 사용 예시는 하단 참조

     

    참고링크:

    https://ko.javascript.info/promise-api

     

     

    [NODE_ENV]

     

    process.env안에 담겨있는 노드 환경을 나타내는 환경변수, 현재 어떤 모드인지를 보여주기위해 사용한다.

     

    production(배포) 모드: 파일 캐싱, 에러 메시지 감추기 등 실제 배포의 적합한 환경 설정

    development(개발) 모드: 파일 캐싱 방지, 디버그를 위한 상세한 에러 메시지 보이기 등
    개발에 도움을 줄 수 있는 환경으로 설정

     

    참고자료:

    https://steemit.com/kr/@inspiredjw/node-js-nodeenv

    https://velog.io/@yhe228/2020-02-08-1102-%EC%9E%91%EC%84%B1%EB%90%A8-o7k6czx831

    https://afrobambacar.github.io/2017/03/proccess-env-of-nodejs.html

     

    ▶ 느낀 점

     

    화상 채팅을 구현하는 데 있어서 리액트 부분에 몇 가지 수정할 부분이 있었다.

    튜터님께 듣기론 'useState()가 각각 하나의 기능만 담고 있어야 한다, Ref와 State는 섞이지 말아야 한다,

    값을 삽일할 때는 push()대신 setState(), map, filter같은 것으로 넣어주어야 한다,

    useEffect()가 어떤 변수를 의존하는지를 마지막 부분에 useEffect(() ⇒ {}, [의존하는 변수])와 같은 형식으로 표기해주어야 한다'와

    같은 것들이 있었다.

     

    사실 아직 리액트를 한 번도 배워보지 못했기에 State가 무엇이고 Ref가 무엇인지, 어떤 원리로 돌아가는지 등

    모르는 것이 많았지만 팀원 분들에게 도움이 되고자 설명을 들으며 최대한 이해한 대로 프로젝트 Docs에 기록해두었다.

    나에겐 당장 도움이 되지 않을지라도 협업하는 우리의 프로젝트에는 분명 도움이 될 것이다.

    +

    백엔드를 하더라도 분명 연관된 프론트엔드의 지식을 배워야할 것이다.

    또, 개발자라면 지식이 변함에 따라 끊임없이 새로운 지식을 받아들이고 적용할 줄도 알아야 한다.

    이럴 때 중요한 것은 모르는 것이더라도 부딪쳐보고 배우며 이것저것 시도하며 내것으로 만드는 것이라고 생각한다.

    위와 같이 최대한 이해하려고 노력한다면 그 다음에 관련 공부를 할 때는 좀 더 수월할 것이다.

    이것이 반복되면 온전한 내것이 될 수 있으리라 믿는다.

    이 중요한 태도를 마음에 되새기며 오늘도 내일도 꿈을 향해 나아가보자 :)

     

    ▶ 공부 시 참고 링크들

     

    https://socket.io/docs/v4/listening-to-events/#socketoffeventname-listener

     

    Listening to events | Socket.IO

    There are several ways to handle events that are transmitted between the server and the client.

    socket.io

     

    https://velog.io/@zerozoo-front/useEffect%EC%99%80-addEventListener

     

    useEffect와 addEventListener

    1\. useEffect의 사용법2\. useEffect와 addEventListener3\. useEffect와 removeEventListenerreact에서 권장하는 useEffect의 사용법은component 내부에서 선언함으로써 state를 사용 가능하게끔 c

    velog.io

     

     

    https://security.stackexchange.com/questions/108662/why-is-bearer-required-before-the-token-in-authorization-header-in-a-http-re#:~:text=Long%20before%20bearer%20authorization%2C%20this,re%20using%2C%20so%20it's%20important.

     

    https://velog.io/@neity16/NodeJS-Token-%EC%A0%80%EC%9E%A5-%EC%9C%84%EC%B9%98%EC%9D%98-%EA%B3%A0%EC%B0%B0

     

    NodeJS - Token 저장 위치의 고찰

    1\. Client가 로그인에 성공하면 Server에서 Token을 발행해서 Response !      (HTTP Response 메시지의 Body에 담아서 )2\. Client는 받은 Token을 저장해둔다3\. 인증이 필요한 Request가 있을 때 서버에 받은

    velog.io

     

    '항해 99' 카테고리의 다른 글

    항해 99 5기 TIL_64  (0) 2022.03.15
    항해 99 5기 TIL_63  (0) 2022.03.13
    항해 99 5기 TIL_61  (0) 2022.03.12
    항해 99 5기 TIL_60  (0) 2022.03.12
    항해 99 5기 TIL_59  (0) 2022.03.10
Designed by Tistory.