캐또's coding

1157 - 단어 공부 - node.js 본문

기초 공부/백준 문제 풀이

1157 - 단어 공부 - node.js

JS_K_coding 2022. 8. 22. 11:06

문제

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

입력

첫째 줄에 알파벳 대소문자로 이루어진 단어가 주어진다. 주어지는 단어의 길이는 1,000,000을 넘지 않는다.

출력

첫째 줄에 이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력한다. 단, 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다.

예제 입력 1 복사

Mississipi

예제 출력 1 복사

?

예제 입력 2 복사

zZa

예제 출력 2 복사

Z

예제 입력 3 복사

z

예제 출력 3 복사

Z

예제 입력 4 복사

baaa

예제 출력 4 복사

A

출처

알고리즘 분류


문제를 어떻게 풀면 좋을지 고민하다가 검색을 통해 여러 문제 풀이들을 살펴봤다. 우선 입력으로 온 값을 대문자/소문자로 통일시킨다. a부터 z까지로 이뤄진 0짜리 배열을 만들고 입력값들을 하나씩 돌면서 해당하는 알파벳을 ++해준다. 마지막에 가장 높은 숫자에 해당하는 알파벳을 출력한다. 만약 같은 값이 2개 이상이라면 ? 를 출력한다.

 

다음으로 알아본 방법은 Object를 사용하는 방법이었다. 처음에는 이해가 되지 않다가 결과적으로는 유사한 방법 그러나 지금까지 사용하지 않았던 방법이라는 점에서 더 나은 방법이라는 생각이 들었다. 대문자 혹은 소문자로 통일하는 것은 같다. Object의 key값은 입력된 문자, 그리고 value 값은 해당 문자의 갯수가 된다. 입력값들을 하나씩 도는 반복문에서, 입력으로 들어온 값과 같은 key가 있다면 value에 ++를 해주고, 입력으로 들어온 것과 같은 key가 없다면 새로 object를 만들고 그 key를 1로 해준다. 이렇게 반복하다보면 각 문자별로 반복이 끝나면 object의 value를 통해 가장 많은 값을 알 수 있다. 그 다음은 앞선 방식과 같이 가장 큰 수가 하나면 그 key를 대문자로 출력하고 두 개 이상이라면 ?를 출력하면 된다.

 

const input = require("fs").readFileSync("/dev/stdin").toString().trim().toUpperCase().split("");
const strObj = {};

for (let i = 0; i < input.length; i++) {
  if (strObj[input[i]] === undefined) {
    strObj[input[i]] = 1;
  } else {
    strObj[input[i]] += 1;
  }
}

첫 번째 줄은 입력으로 들어온 값을 ''로 구분하여 나눠주는 것. 그리고 문자를 모두 대문자로 바꿔주는 것이다. 두 번째 줄에서는 object를 하나 만들어서 들어갈 곳을 만들어준다. for문을 input의 length만큼 돌면서 

만약 strObj에 input[i] key로 해당하는 값이 undefined라면? strObj에 input[i]를 key로 하는 value가 1인 값을 만들어준다.

그렇지 않다면?(해당 값이 있다면?) strObj에서 [input[i]]키에 해당하는 value에 +1을 해준다.

aba라는 입력에 대해서 돈다면?
1. a가 for 문의 첫 번째로 돈다. => strObj에 해당 key가 없다. 당연히 빈 object니까 => undefined이므로 strObj에 a를 키로하고 value를 1로 하는 값을 추가한다. 이제 strObj를 출력하면 { a : 1 }이라고 나올 것이다.
2. b가 두 번째로 돈다 => strObj에 해당 key가 없다. => undefined이므로 strObj에 b를 키로하고 value를 1로 하는 값을 추가한다. 이제 strObj를 출력하면 { a : 1, b : 1 }이라고 나올 것이다.
3. a가 세 번째로 돈다 => strObj에 같은 key가 있다 => strObj의 해당 key 여기서는 a의 값에 +1을 해준다. 이제 strObj를 출력하면 { a : 2, b : 1 }이라고 나올 것이다.

다음으로는 for문을 돌려서 높은 값을 찾아야 하는데 여기서 for ... in을 사용한다. for ... in은 object에서 썼을 때 그 key들을 돌려줄 수 있다. object가 { a : 1, b : 2, C : 3}이라고 한다면 for ( i in object ) {console.log(i)}를 했을 때

a

b

c

가 나오게 된다. 만약 for ( i in object) { console.log(object[i])}를 하게 된다면? object의 key들이 자동으로 바뀔테니

1

2

3

이 나올 것이다.

이것을 활용해본다면 다음과 같이 완성

const input = require("fs").readFileSync("/dev/stdin").toString().trim().toUpperCase().split("");
const strObj = {};

for (let i = 0; i < input.length; i++) {
  if (strObj[input[i]] === undefined) {
    strObj[input[i]] = 1;
  } else {
    strObj[input[i]] += 1;
  }
}
let result = "";
let count = 0;
for (j in strObj) {
  if (strObj[j] > count) {
    result = j;
    count = strObj[j];
  } else if (strObj[j] == count) {
    result = "?";
  }
}
console.log(result);

result와 count를 두고 for문을 돌면서 만약 strObj[j]에 해당하는 값이 count보다 크다면 result와 count를 그 값으로 변경해주고 만약 반복문을 돌다가 count와 새로운 strObj[j]가 같다면 result를 ?로 바꿔주는 방식으로 문제를 해결했다.

 

더 간단하게 예를 들어서 물음표 삼항연산자를 사용하는 방법 등이 있겠지만, 솔직히 아직 익숙한 것은 조금 더 복잡한 지금의 방법이라서 코드가 길어질 수밖에 없었다. 인터넷의 예시로 더 간단히 하는 다른 방법들이 있었는데, 아직은 익숙해지기까지 시간이 더 필요할 것으로 보인다.

'기초 공부 > 백준 문제 풀이' 카테고리의 다른 글

2908 - 상수 - node.js  (0) 2022.08.22
1152 - 단어의 개수 - node.js  (0) 2022.08.22
2675 - 문자열 반복 - node.js  (0) 2022.08.21
10809 - 알파벳 찾기 - node.js  (0) 2022.08.21
11720 - 숫자의 합 - node.js  (0) 2022.08.20
Comments