백준에서 nodeJS 사용하기 (#02): 문자열 - String #1157번 #10809번 #1152번

Kyle Lee·2021년 9월 29일
0

1. 서론

자바스크립트에서 문자열을 잘다룬다면 생각보다 쉽고 편하게 알고리즘 문제를 해결할 수 있습니다. 하지만 JS에서는 문자와 숫자의 타입이 모호하고 정확하지 않은 경우가 있어서 올바른 문자열 문자열 매서드를 활용하는 방법을 아는 것이 중요합니다.

JS.. 독인가 약인가...

이번 글에서는 자주 활용되는 String 매서드의 종류에 대해 알아보고 그 활용법을 실제 문제를 통해 복습해보고자 합니다.

2. String Methods

  • indexOf()
    우선 알고리즘 문제풀이에서 가장 많이 활용되는 문자열 함수는 indexOf 매서드입니다.
String().includes(param)  //String().includes("string") ? true : false
String().indexOf(param)  //String().indexOf("string") ? index : -1

includes는 해당 String 객체에서 입력값이 존재하는지 알려줍니다.
indexOf는 해당 String 객체에서 몇번째 인덱스에 입력값이 존재하는지 알려주고, 없다면 -1을 리턴합니다.
즉, indexOf만으로도 충분히 해당 문자열 객체에 입력값의 존재여부를 알 수 있습니다.

const TEXT = "Kyle loves Javascript";

// indexOf의 args가 string 값 안에 존재하면 index를, 없다면 -1을 리턴한다.
TEXT.indexOf("Kyle") // return : [0]
TEXT.indexOf("l") // return : [2], 중복값이 있을 경우, 첫번째 인덱스만 리턴한다.
TEXT.indexOf("y") // return : [-1]

indexOf는 언제나 첫번째 인덱스만 출력하기 때문에, 만약 중복된 값의 최종 인덱스를 알고 싶다면 lastIndexOf를 사용하면 됩니다.

  • split()
    split은 문자열을 일정 기준으로 나누어 배열을 리턴합니다.
// char를 기준으로 배열 리턴
TEXT.split('') // return : ["K", "y", "l", "e", " ", "l", ...]
// space를 기준으로 배열 리턴
TEXT.split(' ') // return : ["Kyle", "loves", "Javascript"]
// newline(개행문자)을 기준으로 배열 리턴
const LINE = "Kyle\nloves\njavascript";
LINE.split('\n') // return : ["Kyle", "loves", "Javascript"]
  • 기타
    기타 매서드로는 정규표현식으로 인덱스를 검색하는 search(), 모든 문자를 대문자(혹은 소문자 - toLowerCase)로 변환하는 toUpperCase(), 그리고 문자열 앞뒤에 존재하는 공백이나 숨어져있는 공백문자를 제거하는 trim() 등이 자주 쓰입니다.
TEXT.search(/[A-Z]/g) // return : [0] - 대문자 K의 인덱스를 리턴
TEXT.toUpperCase() // return : "KYLE LOVES JAVASCRIPT"
TEXT.trim() // return : "Kyle loves Javascript"

3. 문제 10809번 - 알파벳 찾기

문자열 매서드 split()indexOf()를 활용해 쉽게 문제를 해결해보겠습니다.

해당 문제를 작은 문제로 쪼개보면,
1) 알파벳 배열 생성하기
2) 각 알파벳의 위치(인덱스) 저장하기 입니다.

  • 풀이
const input = require('fs').readFileSync('/dev/stdin').toString().split('');
// split()을 활용해 쉽게 알파벳 배열 생성하기.
const alphabet = "abcdefghijklmnopqrstuvwxyz".split('');

let inputArry = [];

alphabet.forEach(a => {
  	// indexOf()를 통해 각 단어의 인덱스 구하기
    inputArry.push(input.indexOf(a));
});

console.log(inputArry.join(" "));

4. 문제 1157번 - 단어 공부

문자열 매서드 indexOF()lastIndexOf()를 활용해서 다음의 문제를 풀어보겠습니다.

해당 문제를 다시 작은 문제로 나눠보자면,
1) 우선 개별의 문자의 수를 구하고
2) 그 중 가장 큰 값을 찾는 것과
3) 큰 값에 중복이 있는지 여부를 판단하는 것입니다.

  • 풀이
// 대소문자 구별없이 모두 한 문자로 취급하고, 출력은 무조건 대문자이기 때문에
// .toUpperCase()를 먼저 사용해준다.
// 그 다음 각 문자들끼리 정렬해주기 위해 .sort() 처리해준다.
const input = require('fs').readFileSync('/dev/stdin').toString().toUpperCase().split('').sort();

// 집합을 통해 중복제거한 단어 배열 생성
let set = [...new Set(input)];

// 각 문자의 개수를 담을 배열
let arry = [];

// 각 문자의 개수를 구하기 위해 정렬된 문자 배열의 첫번째 인덱스와 마지막 인덱스를 빼준다.
// 물론 이 값에 1을 더해줘야하지만 최대값만 구하면 되기 때문에 생략한다.
set.forEach(a => {
    arry.push(input.lastIndexOf(a) - input.indexOf(a));
});

// 최대값과 값의 인덱스를 구한다.
const maxNum = Math.max(...arry);
const maxIndex = arry.indexOf(maxNum);

// 최대값을 배열에서 제거해보고 중복된 값이 있는지 확인한다.
arry.splice(maxIndex, 1);
if (Math.max(...arry)!==maxNum) {
    console.log(set[maxIndex]);
} else{
    console.log("?");
}

해당 문제를 해결하는 여러가지 방법이 존재하지만, sort()indexOf()를 활용해 각 문자의 개수를 구해보았습니다.

5. 별첨 : 문제 1152번 - 단어의 개수

해당 문제는 쉽게 해결 가능해보이지만 입출력과 관련해서 한가지 함정이 숨어 있습니다.

// 오답!!
const input = require('fs').readFileSync('/dev/stdin').toString().trim().split(' ');
console.log(input.length);

바로 "아무런 입력이 없을 때" 우리의 split()은 빈공간, 즉 ""을 리턴하는 것입니다. 그렇기 때문에 단어의 개수는 0이지만 우리의 배열 길이는 "1"이 존재하는 것이죠.

const input = require('fs').readFileSync('/dev/stdin').toString().trim().split(' ');
if(input[0]===""){
    console.log(0);
}else{
    console.log(input.length);
}

이렇게 예외처리를 해주면 해결할 수 있습니다.

참고 : JS String 문서

profile
필요에 의한 개발

0개의 댓글