ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JavaScript 100제 오답노트 37번_반장선거
    Language/JavaScript 2022. 10. 24. 11:05

    37.  반장 선거

    Q

    새 학기를 맞아 호준이네 반은 반장 선거를 하기로 했습니다. 그런데 표를 하나씩 개표하는 과정이 너무 번거롭게 느껴진 당신은 학생들이 뽑은 후보들을 입력받으면 뽑힌 학생의 이름과 받은 표 수를 출력하는 프로그램을 작성하기로 하였습니다.

    입력
    원범 원범 혜원 혜원 혜원 혜원 유진 유진
    
    출력
    혜원(이)가 총 4표로 반장이 되었습니다.
    //답안
    
    // 1. 입력된 str을 arr로 만든다. => (split)
    // 2. 최다 요소를 뽑는다.
    // -> 배열 요소를 프로퍼티 키로 갖는 객체를 생성하고 요소의 개수를 프로퍼티의 값으로 지정한다.
    // => (for in 문)
    // 3. 최다 요소 갯수를 뽑는다.
    // -> 객체의 프로퍼티 값을 비교한다.
    // => (reduce)
    
    const names = '원범 원범 혜원 혜원 혜원 혜원 유진 유진'.split(" ")
    let result = {};
    let winner = "";
    
    for (const index in names) {
      let key = names[index];
      result[key] = result[key] === undefined ? 1 : result[key] = result[key] + 1;
    }
    winner = Object.keys(result).reduce((a, b) => result[a] > result[b] ? a : b);
    console.log(`${winner}(이)가 총 ${result[winner]}표로 반장이 되었습니다.`)

    -> 이 문제는 생각을 코드로 구현하는 것이 어려웠다. 처음에는 배열 요소가 같은 것들 끼리 다른 배열로 만들어서 각 배열의 길이를 비교하려고 했다. 하지만, 이 방식은 반장 선거 후보로 나온 사람의 수 만큼 새로운 배열이 만들어져야 하므로 효율적인 방법이 아니었고, 심지어 몇 명이 뽑히는지 사전에 알 수 없기 때문에 몇 개의 배열을 미리 생성하여야 하는지도 알 수 없다. 그래서 여기서부터 어떤 식으로 코드를 짜야할지 생각이 나지 않았다. "어떤 새로운 요소가 발견됐을 때 새로운 배열을 만들어서 그 요소의 개수를 계속 카운팅하라"는 코드를 짤 수 없었던 것이다. 짤 엄두가 나지도 않았고 복잡해보였다.

     

    -> 2. 이럴 때일수록 기본 개념에 집중해야 하는 것 같다. 배열은 순서를 가진 자료형이다. 또한 배열의 요소는 index와 value를 갖는다. 따라서 "어떤 이름이 몇개가 카운팅 되었는지"를 하나의 배열요소안에 담으려면 객체형의 요소를 넣어야 한다. 그런데, 지금 내가 2단계(최다 요소를 뽑는다)에서 만들 자료는 "득표 현황"이다. 따라서, 굳이 개인의 득표를 각각의 객체로 만들어서 배열에 담기보다, 그냥 하나의 객체에 key로 분류해두면 된다.

    주어진 배열을 활용해 새로운 객체를 만드는데 for in 문을 활용하면 된다.

     

     -> 3. for in 문을 활용해 득표 현황이 담긴 객체를 완성하면, 객체 프로퍼티의 값을 서로 비교해 가장 큰 값을 가진 객체 키를 꺼내면 된다. 이때는 reduce 함수가 사용된다. reduce는 독특한데 이전 연산의 결과값을 다음 연산에 활용한다. "정반합"의 과정과 유사한 것 같다. 배열에서 사용되면 n-1, n 번째 요소가 연산된 후 나온 결과값과 n+1번째 요소로 또 같은 연산을 반복한다. 이렇게 배열의 끝까지 연산한 결과를 배출하는 함수이다.

    값을 서로 비교할 때 reduce 내장 메소드를 사용하면 편하다.

    댓글