[Algorithm/JavaScript] 문자열 내 p와 y의 개수

Dico·2020년 7월 6일
0

[Algorithm/JavaScript]

목록 보기
5/18

약 한달 전, PREP 개강을 앞두고 선행학습 겸 접했던 문제.
그치만 코딩풋내기에게는 너무나 도전적이어서 좌절감만 맛보고 뒤로 미뤄놨었다 🙈

지금은 할 수 있을까 반신반의하며 오늘 다시 도전해 보았던 결과를 남겨 놓으려고 한다 :)


문제출처: programmers.co.kr (level.1)

문제

문제설명

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

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

제한사항

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


풀이과정

처음 문제를 접하면 주석으로 하고자 하는 일들을 step-by-step으로 정리하면 보다 시작하기가 수월해진다는 피드백을 받았었다.

이를 반영해서 주석으로 문제를 정리해본 후 처음 제출했던 답변은:

function solution(s){
    var answer = true;
//본 문제는 s문자열의 요소인 p와 y의 개수를 비교해 boolean으로 반환하는 문제이다. 
//s문자열을 순회하면서 찾는 요소가 있는지 검사해야하기 때문에 문자열의 길이만큼 반복문을 진행해야한다.
//먼저 s문자열 내 p와 y의 개수를 각각 구해야한다. p와P, y와Y는 같은 것으로 취급한다.
//두 스트링의 개수가 서로 같은 경우 & 모두 하나도 없는 경우(true), 서로 다른 경우(false)로 boolean결과에 따라 크게 2가지로 나눌 수 있다. if문을 사용할 수 있다.
//문자열 내 각각의 p와 y의 개수가 서로 같은지 다른지를 비교해 boolean을 반환하는 것이 반환해야할 최종 답변이 된다. 
    let numP = 0;
    let numY = 0;   
    for(let i = 0; i <= s.length; i++){
        if(s[i] === "P" || s[i] === "p") { 
            numP++; 
        } else (s[i] === "Y" || s[i] === "y") { 
            numY++;  
        }
    }
    if (numP === numY) { 
        return answer;
    } return false;
}

결과는 SyntaxError: Unexpected token '{'
else문에서 문법적에러가 났다는 메세지가 뜬다... 흠
else는 if조건이 아닌 모든 경우이기 때문에 조건문이 기재되어선 안된다❗️

function solution(s){
    var answer = true;
    let numP = 0;
    let numY = 0;   
    for(let i = 0; i <= s.length; i++){
        if (s[i] === "P" || s[i] === "p") { 
            numP++; 
        } 
        if (s[i] === "Y" || s[i] === "y") { 
            numY++;  
        }
    }
    if (numP === numY) { 
        return answer;
    } return false;
}

결과는 성공적!!!

하지만 뭔가 코드가 깔끔하지 않은 것 같은 느낌을 떨쳐낼 수가 없다 🤔

개인적으로 programmers의 가장 좋은점은,
<나의 풀이>에서도 개선된 답변을 제공해준다는 점과, 문제를 풀고다른 사람들의 답변을 보며 간접적이지만 여러가지 경우의 수를 배울 수 있다는 점인 것 같다.

<나의 풀이>는 if문을 2번 사용했던 내 답변이 아래와 같이 if와 else if문으로 개선될 수 있다는 걸 알려준다.

    for(var i=0;i<s.length;i++){
        if (s[i] === "p" || s[i] === "P"){
            pCount++;
        } else if (s[i] === "y" || s[i] === "Y"){
            yCount++;
        }
    }

아무래도 if, else if, else 문의 차이에 대해 좀 더 자세하게 알 필요가 있을 것 같다.
인터넷 검색을 해보니 나랑 똑같은 의문을 가졌던 사람이 있다 😂

이에 대한 베스트 답변은...?

그리고 <모든 풀이> 에서는 다른 사람들의 답변도 볼 수가 있는데,
가장 많은 좋아요를 받은 답변은 아래와 같다❗️

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

오늘의 Lesson

  • 조건문에서
    1) if문을 반복해서 사용하는 것과
    2) if문과 else if문을 사용하는 것의 차이는,
    1)의 경우 가장 첫번째로 오는 조건이 만족하더라도 주어진 조건을 끝까지 비교하게 되지만, 2)의 경우 순차적으로 조건문을 검사하고 조건문이 만족되는 순간 바로 if문을 빠져나간다는 것에 있다.

  • if-else문은 if의 조건이 맞으면 if문의 실행문이 실행되고, 그렇지 않으면 else문이 실행되는 것이다. 'yes가 아니라면 no'의 개념이기 때문에 boolean의 결과에 비유할 수 있다.
    반면, if-else if문은 여러가지 조건을 나열해두고 순차적으로 실행하여 일치하는 조건을 찾는 것에 가깝다고 생각할 수 있다.
    따라서 나의 첫번째 오답에서의 에러가 발생한 이유는 if의 조건문이 충족되지 않으면 대안으로서 else문이 실행되어야 하는 것이 아니라, if문의 조건(문자열s의 i인덱스가 p/P인지)이 충족되지 않는 것과는 별개로 if else문으로 문자열s가 다음 조건(문자열s의 i인덱스가 y/Y인지)은 충족하는 지 검사할 수 있어야 했기 때문이다.

  • <모든 풀이>에서 볼 수 있는.split()메소드는 변수명.split('구분의 기준이 되는 문자열')의 형식으로 사용하며, 하나의 텍스트를 기준이 되는 텍스트(ex. 하이픈(-), 콤마(,) 등)로 분리하여 여러개의 값을 가진 배열로 변환 후 반환해준다. .split.length()는 분리된 문자열의 개수를 반환해준다.

    Ex.

    var beforeStr = "02-123-4567";
    var afterStr = beforeStr.split('-');
    afterStr[0]  // "02"
    afterStr[1]  // "123"
    afterStr[2]  // "4567"
    console.log(afterStr.length);  //3 

    Ex.

    function numPY(s) { 
      console.log(s.toUpperCase().split("P")); 
      //["", "", "AB", "CDE", "FGH", ""]
      console.log(s.toUpperCase().split("P").length); 
      // 6
    }
    
    numPY("pPabPcdepfghp")

Reference

https://okky.kr/article/209530
https://webisfree.com/2014-01-25/[javascript]-%EB%B3%80%EC%88%98%EC%97%90%EC%84%9C-%ED%8A%B9%EC%A0%95%EB%AC%B8%EC%9E%90-%EA%B8%B0%EC%A4%80-%EC%9E%90%EB%A5%B4%EA%B8%B0(%EB%82%98%EB%88%84%EA%B8%B0)-split()

profile
프린이의 코묻은 코드가 쌓이는 공간

0개의 댓글