바닐라코딩 사전학습과정을 마치고 알고리즘 공부를 해보려고 구글링을 통해 어디가 좋을 지 찾아보았다.
대표적으로 프로그래머스, 백준 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)
'바닐라코딩 사전학습 > 추가공부 및 부가설명' 카테고리의 다른 글
절대경로와 상대경로 (0) | 2022.01.08 |
---|---|
no such file or directory 에러 (0) | 2022.01.06 |
JavaScript 와 Node.js (0) | 2021.12.31 |
메모리 주소는 무슨 타입일까? (0) | 2021.12.27 |
크롬 콘솔모드에서 let변수만 재선언이 되는 이유 (0) | 2021.12.24 |