JavaScript/알고리즘

프로그래머스 문자열 내 p와 y의 개수 JS ( split()으로 특정 문자열 몇개 포함하는지 구하기 )

hihiha2 2023. 9. 11. 14:40

🧷 링크

문제 설명

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

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

 

 

 

🙋‍♀️ 내 생각

대/소문자 구분이 없다는 가정이 있기때문에, 대문자나 소문자 하나로 통일하고 시작해야겠다고 생각했다.

 

'p'나 'y'를 얼마나 가지고 있는지 filter()를 통해 조건을 거리고 length를 이용해서 길이를 구한다음, 비교한다.

 

 

 

 

✅ 내 코드

function solution(s){
    const arr = [...s].map(v=>v.toUpperCase())
    
    const pLength = arr.filter(v=>v==='P').length
    const yLength = arr.filter(v=>v==='Y').length
        
    return (pLength === yLength) ? true : false
}

 

우선 s가 string타입이기때문에 배열에 일일이 나눠서 담기위해서 [...s]를 사용했다.

 

그런 다음, 대문자로 만들기 위해서 map을 통해서 배열을 돌면서 toUpperCase()해주었다.

(다 만들고 생각해보니, 저렇게 할 필요없이 toUpperCase()를 먼저하고나서 배열로 만들면 굳이 map을 돌릴필요가 없다😨) 

➡️ const arr = s.toUpperCase().split()

 

다음으로, filter()를 통해서 'P'/'Y'만 남기고, length를 통해 배열의 길이를 잰다.

 

바로 return해도 되지만, 코드를 좀 더 깔끔하게하고 의미를 넣기위해서 const를 사용해서 변수에 담는다.

변수명을 각각 pLength, yLength로 만들었다.

 

그리고 p의 개수와 y의 개수가 같을때=true, 다를 때 false, 둘다 0일때 false로 경우를 나눠야한다.

나눠서 리턴하기 위해서 삼항연산자를 사용한다.

 

그런데 생각해보면, 둘다 0일때도 결국 p의 길이와 y의 길이은 동일하고 둘다 true를 return하기 때문에 굳이 두개를 나눌 필요없이

1️⃣ p의 길이=y의 길이일 경우, true로 2️⃣ 다를 경우, false 로만 나눠도 된다.

삼항연산자를 통해 p,y의 길이가 같을 경우 ? true : 그렇지 않으면 false를 반환한다.

 

 

 

 

 

💻  다른사람 코드중에 배울 것 

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

전체적인 로직은 유사하지만,

1. split(separator)을 사용

2. 삼항연산자를 사용하지 않고 바로 ===를 비교

를 함으로써 코드의 길이가 많이 줄어 들었다.

 

이러한 비교를 위주로 위의 코드를 분석하면 아래와 같다.

우선 s.toUpperCase()로 문자열을 대문자로 만든다.

그런 다음 split("P")을 통해서 문자열에서 P를 기준으로 나눈다.

split()는 separator로 들어간 값기준으로 문자열을 자르고, 그 값을 모아서 배열로 만든다.

 

 


🔫 split(separepor)을 통해서 포함하는 문자열의 숫자를 센다는 것을 이해

🖥 separator를 몇개 포함하고 있는지  = split(separator).length - 1   

split(separator)를 이용하면, 해당 문자을 몇개 포함하고 있는지 알 수 있다.

 

기본적으로 split(구분자)은 구분자를 기준으로 문자열을 자르고, 해당 값들을 배열에 담는 성질을 가지고 있다.

이 성질을 이용해서 해당 구분자를 몇개 가지고 있는지를 알 수 있다.

 

자세한 예시를 보면 조금 더 쉽게 이해할 수 있다.

 

예시

예를 들어 "Hello,World,How,Are,You".split(,)

에서 ,를 구분자로 사용하면 ,를 기준으로 문자열을 자르고 배열에 담는다.

["Hello", "World", "How", "Are", "You"]

 

위의 예시에서 알 수 있듯이 구분자인 ,를 기준으로 문자열을 자르고 배열에 담는다.

이렇게 하면 "Hello" "World" "How" "Are" "You"의 5조각으로 잘린다. 

구분자로 사용된 , 는 문자열에 4개가 포함되어있다.

 

🤔 구분자가 4개이면, 5조각이 된다?

구분자의 수 + 1  = split(구분자).length

구분자 + 1의 결과가 어떻게 나오는지를 더 쉽게 이해하기위해, 아래와 같은 빵을 자르는 것을 상상해본다.

아래의 빵을 / 모양으로 파인 부분을 기준으로 자른다고 해보자. 그러면 빵은 몇조각이 되겠는가?

➡️ 당연히 5조각이 될 것이다.

 

구분자의 개수  = split(구분자).length -1 

그래서 해당 문자열이 포함하고 있는 구분자의 수를 구하기 위해서는 위와같은 식이 나온다.

위의 식에서 +1을 우변으로 옮기면서 -1로 바뀐다.

 

구분자의 수 + 1 = split(구분자).length

1을 우변으로 옮기기 전의 식

 

 

위와 같은 성질을 이용하면, split()을 이용해서 문자열에 특정문자열이 몇번 포함되어있는지를 검사할 수 있다.

위에 내가 원래 만든 코드처럼 filter를 통해서 해당값만 찾아서 length를 찾아도 되지만 split()으로 찾는것이 조금 더 간단하다.

 

🤔 그럼 구분자가 문자열의 맨 끝에 위치한다면?

이라는 의문이 생길 수 있다.

 

구분자가 문자열의 끝에 위치해도 split()을 통해서 구분자의 수를 구할 수 있을까?

➡️ 가능하다.

 

구분자가 끝에 위치하면, 끝에 빈문자열""을 생성하여 배열에 포함하는 성질때문이다.

위의 성질은 아래의 문제를 풀면서 정리한 적이 있다.

 

 

 

프로그래머스 문자열 잘라서 정렬하기 JS (split()의 구분자가 문자열 끝에 위치한다면? / match()의

문제 설명 문자열 myString이 주어집니다. "x"를 기준으로 해당 문자열을 잘라내 배열을 만든 후 사전순으로 정렬한 배열을 return 하는 solution 함수를 완성해 주세요. 단, 빈 문자열은 반환할 배열에

hihiha2.tistory.com


 

다시 문제로 돌아가보면, 

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

대문자로 만들어준 문자열을 split()을 통해서 "P"나 "Y"를 기준으로 자르고 배열에 담는다.

이때 -1을 해줘야 구분자의 개수를 구할 수 있지만, 양쪽 모두 -1을 해줄 것이므로 이 과정을 생략해도 결과는 같다.

 

그런 다음, length를 통해서 개수를 구한다.

이렇게 구한 length을 ===을 통해서 값이 같은지 비교한다.

 

굳이 삼항연산자를 사용하지 않고, 바로 값을 비교함으로써 코드가 조금 더 간결해졌다.

===으로 비교해도 어차피 값이 boolean값으로 나오므로 굳이 삼항연산자를 사용해야하는 것은 아니다.

 

 

 

🙋‍♀️ 내 생각

처음에 split()을 이용해서 문자열에 포함된 특정 문자의 숫자를 샌다는 것을 생각하지 못했는데,

"자르고 나눈다"라는 원리를 생각해보면 당연히 가능한 일이었다. (위에 생각한 빵처럼!!)

 

메세드들도 꽤 익숙해졌다고 생각해보 이해하면 할수록, 더 많은 이용법이 있음을 느낀다.

다양한 상황에서 많이 사용함으로서 더 능숙하게 사용할 수 있도록 해야겠다. 🤓