문자열 내 p와 y의 개수(Javascript)

·2022년 9월 15일
0
post-thumbnail

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

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

제한사항

문자열 s의 길이 : 50 이하의 자연수
문자열 s는 알파벳으로만 이루어져 있습니다.

입출력 예

sanswer
"pPoooyY"true
"Pyy"false

입출력 예 설명

입출력 예 #1
'p'의 개수 2개, 'y'의 개수 2개로 같으므로 true를 return 합니다.

입출력 예 #2
'p'의 개수 1개, 'y'의 개수 2개로 다르므로 false를 return 합니다.

나의 풀이


function solution(s){
    const separate = [...s];
    const countP = separate.filter(element=> ('P'=== element ||'p' === element)).length;
    const countY = separate.filter(element=> ('Y'=== element ||'y'=== element)).length;
    let answer;
    if (countP===0 && countY===0){
        answer = true;
    }
    else if(countP === countY){
        answer = true;
    }
    else
        answer = false;
   return answer;     
}

..풀긴 풀었는데 좀 더럽게 풀었다. 이번에는 문자를 배열로 나눌 때 [...](spread syntax)기능을 활용해 보았다. 이 문제에서는 문자가 알파벳으로만 이루어져 있으므로 상관 없겠지만 특수문자를 split()으로 나누면 오류가 발생하기 때문에 ES2015의 새로운 기능인 [...]을 사용하길 권장한다고 나와 있어서 한 번 써 봤다. 참고

그리고 filter()기능을 써 줬다. filter()는 배열에서 특정 조건을 만족하는 요소들을 찾아 다시 배열로 반환해준다. 그리고 length를 사용해 배열의 숫자를 세줬다. 이후에 if문을 이용하여 p의 갯수와 y의 갯수를 비교해 같다면 true를, 같지 않으면 true를 인출해 줬다.
... 다른 사람의 풀이를 참고하자

참고할 풀이 1

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

나도 대소문자를 바꾸기 위해서 toUpperCase를 사용하려고 해 봤는데 toUpperCase는 문자열을 전부 대문자로 바꿔주는 함수라서 배열로 만든 이후에는 사용이 안 됐었다. 근데 생각해보니까 배열로 만들기 전에 주면 되네.. 바보였다 졸린것 같다 지금
그리고 이 케이스는 p와 y만 비교하는데 p와 y가 없을 때의 경우는 넣지 않은 듯 하다.

참고할 풀이 2

const noPY = true;
if 
function numPY(s) {
  return s.match(/p/ig)?.length == s.match(/y/ig)?.length;
}

match()함수는 파라미터로 정규식을 준 다음 문자열과 정규식이 일치하는 부분을 찾는다. 정규식은 패턴을 사용해 텍스트를 판별하는 데 사용하는 것이다. 정규 표현식은 기본적으로 슬래시(/)로 문자열을 감싸서 표현해 준다. 예를 들어 /p/는 문자열 p를 찾아달라는 의미이다. 정규 표현식은 전역 탐색이나 대소문자 무시 같은 특성을 지정하는 플래그를 가질 수 있다. 플래그는 /pattern/flag; 이런 식으로 지정해 줄 수 있다. i는 대소문자 무시, g는 전역 탐색이므로 p를 찾는데 전체에서 대소문자를 무시하고 준다면 /p/ig로 정규식을 작성해 줄 수 있다.

참고 : 자바스크립트 공식 문서

p와 y둘 다 들어있지 않은 예외를 설정하려면 .length 앞에 ?를 붙여주면 된다. 이것을 옵셔널 체이닝(optional chaining)이라고 하는데, 앞의 값이 Null이나 undefined이면 undefined를 반환한다. length함수는 null.length를 해주면 오류가 나지만 undefined.length를 해주면 undefined를 반환한다. p와 y 둘 다 존재하지 않을 때 undefined == undefined이므로 true를 반환한다.

참고할 풀이 3

function numPY(s){
  var result = true;
  s = s.toUpperCase();
  var num = 0;
  for(var i = 0; i < s.length; i++){
    if(s[i] === 'P') num++;
    if(s[i] === 'Y') num--;
  }
  result = (num === 0);

  return result;
}

이 풀이는 p와 y를 찾을 때 반복문을 이용해 준 풀이이다. 미리 result를 true로 선언하여 만일 p와 y가 없는 경우에는 true가 출력되도록 만들어 주었다. 그리고 반복문에서 p가 나오면 숫자를 하나 올려주고, y가 나오면 숫자를 하나 내려 주었다. 그래서 결과적으로 num이 0이면 true, 거짓이면 false를 출력해 주었다. 나는 가독성을 위해 반복문 대신 filter함수를 사용해 줬는데, 코드 결과를 보니 차라리 반복문이 더 간결하고 이해가 쉬운 느낌이다.

참고할 풀이 4

function solution(s){

    return [...s.toLowerCase()].reduce((acc, cur) => {
        if(cur ==='p') return acc + 1;
        else if(cur ==='y') return acc - 1;
        return acc;
    }, 0) ? false : true;
}

여기에서는 특이하게 toLowerCase()를 써 줬다. 문자를 전부 소문자로 바꿔주는 기능인데, 내가 알아봤을 때는 어떤 문자의 경우는 소문자로 변환이 되지 않는 경우가 있어서 대소문자 구분 없이 쓰려면 대문자로 쓰는 게 좋다고 한다. 여기서는 reduce() 함수를 써 줬는데, 논리 자체는 위의 풀이 3과 비슷한 듯 하다. reduce() 함수는 현재 값에 함수를 통과한 값을 누적시켜 주는 함수이다. 만약에 배열에 p가 있다면 누적 값에 1을 더해 주고, y가 있다면 누적 값에 1을 빼 준다. 만약 p와 y값이 같다면 0이므로 false, 같지 않다면 0이외의 숫자이므로 true가 나온다. 삼항연산자를 이용해 true일때 false를, false일 때 true를 인출해 준다. p와 y가 없다면 acc는 0이므로 true를 인출해준다.

profile
전 이것도 몰라요

0개의 댓글

관련 채용 정보