개발/코딩테스트

[백준 | JavaScript] 1157 단어 공부

prpn97 2023. 5. 22. 20:05

문제 설명

알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

 

입출력

input output
Mississipi ?
zZa Z

문제 설명

const fs = require("fs");
let input = fs.readFileSync("./input.txt").toString().trim()
let str = input.toUpperCase()

let words = new Object()
for(let i = 0; i < str.length; i++){
  if(words[str[i]]===undefined){
    words[str[i]] = 1
  }else words[str[i]]+=1

}
let wordsArr = Object.entries(words).sort((a,b)=>b[1]-a[1])
wordsArr.length===1 ? console.log(wordsArr[0][0])
:wordsArr[0][1]===wordsArr[1][1] 
? console.log('?')
: console.log(wordsArr[0][0])

가장 많이 사용된 알파벳을 반환하며 둘 이상일 경우 ?을 반환하는 문제이다. 

대소문자를 구분하지 않으며, 대문자로 반환해야 하기 때문에 모든 문자를 대문자로 바꿔준다. 

어떻게 글자를 셀지 고민하다가 이전에 푼 문제 중에 객체에 값을 넣어서 비교했던게 떠올랐다.

 

new Object()로 words라는 새 객체를 만들어주고,

그 안에 str[i]가 undefined일 경우 (해당 값이 없을 경우) str[i]를 1로 설정한다. 

apple이라고 하면, 처음에 words는 {} 이므로 아무것도 들어있지 않아서

str[0]인 a의 값이 확인되지 않는 undefined이므로, words[str[0]]인 A가 1이 된다.

즉, { A: 1 } 이 되는 것이다. 그리고 str을 돌면서 같은 글자가 있으면 1을 더해준다. 

{ A: 1, P: 2, L: 1, E: 1 } 이런식으로 P는 1이 늘어날 것이다. 

 

여기서 객체를 sort하는 방법을 몰라서 찾아보니, 배열로 바꿔주는 방법이 있었다.

Object.entries()를 사용하면 객체가 키-요소를 쌍으로 가진 배열로 바뀐다. 

wordsArr = [ [ 'A', 1 ], [ 'P', 2 ], [ 'L', 1 ], [ 'E', 1 ] ]  이런식으로 말이다. 

 

이젠 쉽다. wordsArr을 sort로 내림차순으로 정렬하여 가장 큰 값을 먼저 정렬한다.

맨 처음 인덱스가 가장 클 것이다. 그리고 같은 값이 둘 이상일 경우를 비교해야 하는데

애초에 값이 1개이면 1번 인덱스를 비교할 수 없으므로 값이 1개면 바로 0번 값을 반환한다.

그리고 0번째, 1번째 인덱스가 같을 경우 ?를 반환하고, 

아닐 경우 0번째 인덱스를 반환한다.

 

코멘트

문제를 풀고 나서 다른 사람들의 풀이를 살펴봤는데, 객체로 푸는 방법보다는

배열을 각 알파벳 개수만큼 요소를 넣어서 카운트하는 방법이 많았다.

charCodeAt을 사용하면 알파벳의 아스키코드값으로 변환되는데,

a가 65이므로 입력되는 알파벳에서 65를 빼서 그 값을 인덱스값에 넣어

각 알파벳이 지정된 위치에 카운트되는 방법인 것 같다. 

 

아직 부족한 지금의 내 머리로는 내가 한 방법이 더 괜찮은 것 같다.

둘 다 결국 알파벳을 카운트하는데, 후자의 경우는 26개의 알파벳 배열을 담고 시작한다.

입출력 예시도 그렇고 26자가 안되는 입력값의 경우 굳이 26개의 요소를 담을 필요는 없기에

필요한 개수만큼만 확인한 방법이라는 생각이 든다. 

 

728x90