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

2021. 3. 29. 13:44Front-end/알고리즘

728x90
반응형

안녕하세요. 이번 시간에는 백준에서 node.js 입출력 방법에 대해 알아보겠습니다.

자바스크립트로 코딩테스트를 준비할 경우, 백준에서는 node.js를 선택하여야 합니다.

그런데 node.js가 좀 번거롭습니다.

프로그래머스에서는 입출력은 상관 없이 함수 하나만 작성하면 되었는데 백준에서는 입력과 출력을 직접 해주어야 합니다.

그럼에도 불구하고 프로그래머스보다 백준이 문제가 훨씬 많으므로 node.js 입출력 방법을 정리해보도록 하겠습니다.

 

백준에서 node.js 입출력 방법으로 사용하는 방법은 크게 두 가지가 있습니다.

아직 어떤 차이가 있는지는 잘 모르나,

fs 모듈의 경우 코드가 간단하고 다른 블로거 분들의 말을 보니 readline으로 시간초과가 나올 때 사용한다고 합니다.

저는 vscode에서 먼저 테스트해보고 제출하려고 여태 readline을 사용했었는데

fs 모듈을 사용하더라도 vscode에서 사용할 수 있는 방법도 밑에서 알려드리겠습니다.


fs 모듈을 이용하는 방법(백준 제출용)

1) 한 줄로 입력을 받을 때

//한 줄 입력

let fs = require('fs');
let input = fs.readFileSync('/dev/stdin').toString().split(' ');

let num = Number(input);

for (let i = 1; i <= num; i++) {
  console.log(i);
}

2) 여러 줄로 입력을 받을 때

//여러 줄 입력

let fs = require('fs');
let input = fs.readFileSync('/dev/stdin').toString().split('\n');

let count = input[0];
let numbers = [];

for (let i = 1; i < input.length; i++) {
  if (input[i] !== '') {
    numbers.push(input[i].split(' '));
  }
}

for (let i = 0; i < numbers.length; i++){
  let num1 = Number(numbers[i][0]);
  let num2 = Number(numbers[i][1]);

  console.log(num1 + num2);
}

fs 모듈을 이용하는 방법(vscode에서 테스트용)

🍼 우선 vscode에서 'npm install fs'로 파일시스템을 설치해줍니다.

🍼 저는 문제를 풀 때마다 예제.txt에다가 예제를 복사한 후 실행해볼려고 예제.txt를 만들었습니다.

🍼 아래와 같이 readFileSync의 경로를 예제.txt의 위치로 수정해주면 됩니다. (이후 다음 방법은 백준 제출용과 같습니다. readFileSync로 txt 파일을 읽어와서 toString과 split을 이용하여 배열로 만들어 input으로 저장한 것이기 때문에 나머지는 알아서 유동적으로 수정하여 사용하면 됩니다. Number 메소드를 이용하여 숫자로 변경한다던지.. )

🍼 vscode에서 실행할 때에는 ctrl+ ` 키를 이용하여 콘솔을 켜준 후 콘솔창에 'node 현재작성한js파일경로' 이렇게 써주시면 되고, 파일경로는 참고로 현재 작성한 js 파일을 vscode에서 오른쪽마우스를 누르면 Copy relative path가 나오는데 그걸 눌러서 복사하면 됩니다. 

 

let input = require('fs').readFileSync('예제.txt').toString().split('\n');

백준에서는 /dev/stdin 경로를 이용하지만, 백준 코드 제출창에서는 채점만 해주고 어떤 식으로 나오는지 테스트를 해볼 수가 없으니깐 위와 같이 해서 vscode에서 먼저 문제를 풀어보고 제출할 때에는 readFileSync만 /dev/stdin으로 수정하여 제출하면 됩니다. 

 

예를 들어 저는 백준에서 15552번 문제인 '빠른 A+B'를 풀려고 하는데요 이 문제의 경우 테스트케이스 개수가 최대 1,000,000이나 되기 때문에 입출력 방식이 느리면 여러 줄을 입력받거나 출력할 때 시간초과가 날 수 있다고 합니다.

(원래 저는 fs 모듈 말고 readline 방식을 사용해서 문제를 풀었었는데 정말 시간초과가 나서 fs모듈 방식을 사용했습니다.)

 

저는 이렇게 현재 js파일을 만들었고 예제 용 txt 파일도 만들었습니다.

예제.txt에는 문제에서 주어진 예제 입력을 그대로 복사해서 저장해주었습니다.

 

let input = require('fs').readFileSync('예제.txt').toString().split('\n');
let count = Number(input[0]);
let answerStr = '';

for(let i = 1; i <= count; i++){
    let num = input[i].split(" ");
    answerStr += Number(num[0]) + Number(num[1]) + "\n";
}

console.log(answerStr);

vscode에서 테스트해보기 위해 readFileSync에 경로를 저렇게 적어주었습니다. (위에서 말했듯 제출할 때에는 저 부분을 /dev/stdin 이라고 바꾸면 됩니다.) 

 

마지막으로 실행해보기 위해서 콘솔창에 다음과 같이 치면 실행이 됩니다.


readline으로 사용하는 방법

1) 한 개의 입력만 받을 때

//한 개의 입력(띄어쓰기x)
function solution(input){
    console.log(input);
}

const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
let input;
rl.on("line", function(line){
    input = line;
    // input = parseInt(line); // 입력 값이 정수라면 parseInt로 형변환
    rl.close();
}).on("close", function(){
    solution(input);
    process.exit();
})

 

2) 한 줄의 입력을 받을 때 (띄어쓰기로 구분)

//한 줄의 입력(띄어쓰기 o , 예를 들면 1 2 3 4 5)
function solution(input){
    const [a,b] = input;
    const answer = a+b;
    console.log(answer);
}

const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
let input;
let list = [];
rl.on('line', function(line) {
    input = line;
    rl.close();
}).on("close", function() {
    // list = input.split(' ').map((el) => el); 
    list = input.split(' ').map((el) => parseInt(el)); // 입력값이 정수라면 parseInt로 형 변환
    solution(list);
    process.exit();
});

 

3) 여러 줄의 입력을 받을 때

//여러줄  입력시(n, input)
function solution(n, input) {
    console.log(n);
    console.log(input);
}

const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});
let input = [];
rl.on("line", function(line) {
    input.push(line)
    //rl.close()가 없어서 계속 입력
    //로컬에서 입력을 중지하려면 입력을 한 후 ctrl+d로 입력 종료
}).on("close", function() {
    let n = parseInt(input[0]);
    let list = input[1].split(' ').map((el) => parseInt(el));
    solution(n, list);
    process.exit();
});


//여러줄 입력시(input1, input2)
function solution(input1, input2) {
    console.log(input1);
    console.log(input2);
}

const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});
let input = [];
rl.on("line", function(line) {
    input.push(line)
    //rl.close()가 없어서 계속 입력
    //로컬에서 입력을 중지하려면 입력을 한 후 ctrl+d로 입력 종료
}).on("close", function() {
    let list1 = input[0].split(' ').map((el) => parseInt(el));
    let list2 = input[1].split(' ').map((el) => parseInt(el));
    solution(list1, list2);
    process.exit();
});
728x90
반응형