멋사 회고조에서 매일 코딩테스트 스터디를 진행중이다!
오늘의 문제는 [프로그래머스 LV.1 - 문자열 내 p와 y의 개수] 였다.
대문자와 소문자가 섞여있는 문자열 s가 주어집니다.
s에 'p'의 개수와 'y'의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요.
'p', 'y' 모두 하나도 없는 경우는 항상 True를 리턴합니다. 단, 개수를 비교할 때 대문자와 소문자는 구별하지 않습니다.
예를 들어 s가 "pPoooyY"면 true를 return하고 "Pyy"라면 false를 return합니다.
그렇다면 나는 !
정규표현식으로 문자열 내 p와 y를 찾아서 length를 비교해주어 간단하게 문제를 풀 수 있을거라고 생각했다!
그리하여 첫번째로 작성한 코드.
문제는 계속 2개의 테스트케이스에서 런타임 에러가 났다 ㅠㅠ
if 문으로 조건식도 걸어보고, 모든 변수들과 return 값을 콘솔에 찍어서 하나하나 확인해봐도
정상적으로 출력이 되었다... 그러면 도대체 왜...!!!!! 에러가 나는걸까
프로그래머스에서 런타임에러가 어떤 상황에 발생하는지 구글링해보니 보통
히든케이스 또는 문법 에러인 경우가 대다수라고 한다.
그래서 먼저 메서드부터 다시 확인해보기로 한다.
처음에 이 메서드를 사용할 때까지만 해도 짧은 코드로 y와 p를 검색해낸다는 생각에 행복해서 큰 의심없이 바로 사용했다. 하지만 ? 확인하지 않고 사용한 것이 결국 원인이 되었다. mdn을 정독하다 놀라운 사실을 발견하게된다.
문자열이 정규식과 일치하는 것이 없으면 null이 반환됩니다.
문자열이 정규식과 일치하는 것이 없다면 0이 반환될 것이라 생각하고 코드만 봤을땐
아무 문제가 없다고 생각했던 나에겐 충격 그 자체..
match가 문제가 되었을 거라곤 생각을 못했었다 😂
만약 문자열 s에 p나 y가 포함되지 않았다면, match()에서 null 값을 반환했을거고,
null은 .length 메서드를 가지고 있지 않으니 당연히 에러가 나는 것이었다....!
일단은 성공한 코드!
findP, findY 에서 match 메서드를 사용하며 null 값을 반환할 수 있으므로,
.length 메서드는 return 할때 사용했다.
findP와 findY가 모두 null 일 경우,
OR 둘중 하나만 null 값일 경우를 고려해서 예외처리를 해주었다.
테스트를 통과하고 다른 분의 코드를 구경해보다가
이렇게 한줄만에 풀어낸 간지나는 코드 발견....!
?. 옵셔널 체이닝을 사용해서 깔끔하게 통과한 코드였다.
?.은 ?.'앞’의 평가 대상이 undefined나 null이면 평가를 멈추고 undefined를 반환합니다.
일치연산자 ===를 기준으로 왼쪽, 오른쪽 항에 있는 값이 null을 반환하여도
undefined를 반환하게된다.
undefined === undefined는 true를 반환하므로 결과적으로 문제의 조건을
잘 해결하는 코드였다.
하지만 '옵셔널 체이닝'은 코딩테스트에서 사용하는 것을 지양해야한다고 한다.
보통 데이터를 받아올 때 비동기로 받아오면 값을 받기 전에 변수가 먼저 사용되어서 undefined를 반환하게 되는경우 자주 사용한다.
그런데 코딩테스트에서는 구해야 할 답과 문제가 명확하게 있으니,
옵셔널 체이닝의 목적과 맞지 않는다고 볼 수 있을 것 같다.
앞으로 메서드를 사용할 때 어떤 타입에 사용할 수 있는지, 어떤 값을 반환하는지 등
꼼꼼하게 확인 후에 사용해야겠다고 생각했다.
아직 자유자재로 메서드를 사용할 수 있는 단계이기에 ,
알고있다고 생각이 드는 것 까지 모두 하나하나 확인하면서 기초를 튼튼히 다져야겠다고 생각했다.
그리고 수정한 코드에서, if문을 두개 써준 것이 너무나 아쉬운데,
더 효율적으로 짤 수 있는 방법을 고민해봐야겠다.
똑같은 문제로 에러나서 왜 에러지? 하다가 원인을 찾게됐네요 ㅠㅎ 감사합니다