[프로그래머스]문자열 내 p와 y의 개수

jaemin·2020년 10월 23일
0

프로그래머스

목록 보기
7/18
post-thumbnail

문자열 내 p와 y의 개수

대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 'p'의 개수와 'y'의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. 'p', 'y' 모두 하나도 없는 경우는 항상 True를 리턴합니다. 단, 개수를 비교할 때 대문자와 소문자는 구별하지 않습니다.

예를 들어 s가 pPoooyY면 true를 return하고 Pyy라면 false를 return합니다.

1차 풀이 과정 설계

이 문제를 보고 생각한 알고리즘은 s를 순회하면서 모든 p와 y의 개수를 세서 짝수면 true를, 홀수면 false를 return하는 함수를 만들고 싶었다. p와 y가 짝이 맞는다면 짝수고 둘 중 하나라도 많거나 적다면 홀수일거라고 생각했다.

이 생각을 바탕으로 코드를 짜보았다.

function solution(s) {
  const pPyY = /^[py]+$/i;
  let count = 0;
  if (!s) return true;
  for (let i = 0; i < s.length; i++) {
    pPyY.test(s[i]) ? ++count : count;
  }
  return !(count % 2);
}

그런데 이 코드는 오류를 발생시킨다. 만약 pYyy같은 문자열이 들어온다면 p와 y의 짝이 맞지 않지만 개수는 4개로 짝수가 나와 true를 반환한다.
눈물을 머금고 모두 지우고 새로운 방법을 떠올렸다.

2차 풀이 과정 설계

p와 P, y와 Y는 모두 하나의 문자로 카운트된다. 두 개를 각각 선별해서 카운트하기 어려우니 모두 대문자로 바꿔 계산하기로 했다.
그 다음 문자열 s를 순회하면서 filter() 메서드로 요소값이 'P'와 'Y'를 추려내고 둘의 길이를 비교해서 같다면 true, 다르다면 false를 반환하기로 했다.

function solution(s) {
  return s.toUpperCase().split('').filter(P => P === 'P').length === s.toUpperCase().split('').filter(Y => Y === 'Y').length;
}

이렇게만 해주니 s에 아무것도 주지않았을 때 오류가 나온다. 이에 대한 방어코드도 짜주어야 한다.
s에 아무것도 주지 않으면 undefined, 혹은 빈 문자열이 들어가면 모두 falsy값이 된다.

function solution(s) {
  if (!s) return true;
  return s.toUpperCase().split('').filter(P => P === 'P').length === s.toUpperCase().split('').filter(Y => Y === 'Y').length;
}

다른 사람의 풀이

function solution(s) {
  return s.toUpperCase().split("P").length === s.toUpperCase().split("Y").length;
}

나는 s가 배열이 아닌 문자열이라 고차 함수를 사용할 수 없어서 split()을 사용해서 배열로 바꿔주었다.
그런데 다른 사람은 split을 다르게 이용했다. 만약 s안에 P와 Y의 숫자가 같고 각각 P와 Y를 기준으로 단어를 쪼갠다면 그 쪼갠 덩어리의 숫자가 같을 것이다.
따라서 filter를 사용해서 P인 것만 추려내는 작업을 하지 않아도 된다.

function solution(s) {
  return s.match(/p/ig).length == s.match(/y/ig).length;
}

match메서드를 사용해서 짧게 해결했다.

profile
프론트엔드 개발자가 되기 위해 공부 중입니다.

0개의 댓글