본문 바로가기
바닐라코딩 사전학습/추가공부 및 부가설명

백준 알고리즘에서 자바스크립트로 문제풀기

by 꼬마보노 2022. 1. 6.

바닐라코딩 사전학습과정을 마치고 알고리즘 공부를 해보려고 구글링을 통해 어디가 좋을 지 찾아보았다.

대표적으로 프로그래머스, 백준 BOJ, Leetcode(외국사이트)가 있는데 이 중에 문제가 가장 많고 난이도별로 선택할 수 있는 백준 알고리즘으로 시작하기로 하였다.

그러나 처음부터 난관에 부딪혔는데, 백준 알고리즘은 Node.js를 이용한 입출력을 입력받아서 문제를 풀어야 한다.

제시해주는 입력을 핵심코드만 작성해서 출력을 내는것이 아닌, 입력을 정제(파싱, parsing) 시켜주는 코드를 작성한 후 이 코드의 출력을 입력으로 하는 핵심코드를 작성해야 한다.

C++은 white space(' ', \n, \t)를 기준으로 하나씩 입력을 받는 'cin' 키워드를 통해 입력받을 수 있고,

코드작성시에는 조금 번거롭지만 변수의 타입을 지정해주는 int, char등의 키워드를 통해 입력값의 타입을 지정해줄 수 있다.

처음에는 도대체 무엇을 해야한다는 건지 정말 몰랐지만 어차피 해야 할 일이므로 한번 정리해보려고 한다.

 

BOJ 4344번 문제의 입력

5
5 50 50 70 80 100
7 100 95 90 80 70 60 50
3 70 90 80
3 70 90 81
9 100 99 98 97 96 95 94 93 91

파일 불러오기

const fs = require('fs');
let input = fs.readFileSync('./inoutExample/input.txt', 'utf8');   //.toString().split('\n').map(());

fs변수에 require메서드를 할당해서 필요한 파일을 불러온다. require메서드는 파일을 불러온다. 

'fs'는 파일시스템이다.
require의 속성 중 redaFileSync메서드는 파일을 동기방식으로 읽는다. 첫번째 인자는 경로/파일명, 두번째 인자는 불러오는 불러오는 방식이다.
readFileSync를 통해 test.txt라는 파일을 읽어서 input변수에 문자열로 할당한다.
JS는 파일을 한번에 읽어서 문자열 형태로 저장한다.

 

입력 정제과정

input = input.split('\n');

const testCaseNum = +input[0];

for(let i = 1; i <= testCaseNum; ++i) {
    const arr = input[i].split(' ')    //.map((item) => +item); 아래 3줄의 코드를 이 한줄로 대체가능.
    let newArr = [];
    for (let i = 0; i < arr.length; ++i){
        newArr.push(Number(arr[i]));
    }
    console.log('arr : ', arr);
    console.log('newarr : ', newArr);
    break;
}

 

input = input.split('\n');

input변수에는 현재 문자열이 저장되어 있다. 

해당 문자열을 split메서드를 이용해서 줄을 기준으로 나누는 작업을 거친다.

 

const testCaseNum = +input[0];

number(input[0]);와 같다. +연산자를 쓰면 뒤에오는 값이 숫자가 아닌 경우 숫자로 바꿔준다.
그냥 input[0];을 입력하면 문자 '5'가 들어가게 된다. 따라서 숫자로 바꿔주는 작업을 해줘야 한다.

 

for(let i = 1; i <= testCaseNum; ++i) {
    const arr = input[i].split(' ')    //.map((item) => +item); 아래 3줄의 코드를 이 한줄로 대체가능.
    let newArr = [];
    for (let i = 0; i < arr.length; ++i){
        newArr.push(Number(arr[i]));
    }
    console.log('arr : ', arr);
    console.log('newarr : ', newArr);
    break;
}

두번째 줄의 5 50 50 70 80 100 에서 5는 뒤에 오는 배열의 길이를 의미하므로 또 따로 분리시켜줘야한다. 또한 뒤에 오는 값들도 모두 '숫자'로 바꿔줘야한다. -> 공백을 기준으로 분리하자!

 

입력값 정제시의 팁

1. 입력을 읽어오면 console.log를 찍어서 어떻게 들어왔는지 확인해보자
2. 들어온 값을 어떻게 나누어야 할 지 생각해보자
3. 한가지 작업을 수행하면 다시 console.log를 찍어서 확인 후 1, 2를 반복하자


입력정제코드와 문제풀이코드의 분리

위의 과정에서 좀 더 정제를 하면 입력정제코드와 문제풀이코드를 분리해서 작성할 수 있다.

코딩테스트나 프로그래머스에서는 정제된 입력값이 주어지고 문제풀이코드만 작성하면 되는데 BOJ에서도 두 코드를 분리해서 각각 작성하는 연습을 해보자.

 

진행과정

1. 문제를 풀 때 solution 함수를 만든다. 어떤 입력이 들어오면 문제를 풀 수 있을 지 생각해본다. 그 입력을 매개변수로 사용한다.
2. 입력이 어떤식으로 들어오면 좋을지 주석으로 적어보자.
3. 작성한 입력(input.js)을 바탕으로 1, 2를 수행한다.

 

예시)

/*C = 5;
testCase = [
    {
        N: 5,
        arr: [50, 50, 70, 80, 100]
    },
    {
        N: 7,
        arr: [100, 95, 90, 80, 70, 60, 50]
    }
    ...
]
*/
testCase의 숫자를 C로 입력받고 각각의 테스트 케이스는 첫번째 숫자와 이후의 숫자들을 각각 나누는 것이 좋겠다. 라고 생각하자.

 

const fs = require('fs');
let input = fs.readFileSync('./inoutExample/input.txt', 'utf8');


input = input.split('\n');
// console.log(input); //여기서 생성된 배열의 첫번째 값이 C가 된다.
const inputC = +input[0];
const inputTestCase = [];

for(let i = 1; i <= inputC; ++i) {
    const arr = input[i].split(' ') .map((item) => +item);
    // console.log(arr);
    const newArr = [];
    for(let i = 1; i <= arr[0]; ++i){ //37번째 줄의 console.log의 결과를 보고 arr값을 결정하였다. arr의 첫번째 값을 제외한 값을 넣어주는 for문
        newArr.push(arr[i]);
    }
    const testCase = { //41번째 줄의 console.log의 결과를 보고 N과 arr값을 결정해주었다.
        N: arr[0],
        arr: newArr,
    };
    inputTestCase.push(testCase);
}
console.log('inputTestCase : ', inputTestCase); //입력을 확인


function solution(C, testCase) {}; //문제를 푸는 코드

solution(inputC, inputTestCase);

 

참조)

[백준]백준에서 node.js 입출력 방법 정리(백준/자바스크립트/코딩테스트/알고리즘) (tistory.com)

초보자가 자바스크립트로 백준 문제 푸는 법 - YouTube