문자열 나누기 [프로그래머스 Lv1]

hyo·2023년 3월 19일
0

코딩테스트 준비

목록 보기
8/8
post-thumbnail

문자열 나누기 (프로그래머스 Lv1)

문제설명

문자열 s가 입력되었을 때 다음 규칙을 따라서 이 문자열을 여러 문자열로 분해하려고 합니다.
먼저 첫 글자를 읽습니다. 이 글자를 x라고 합시다.
이제 이 문자열을 왼쪽에서 오른쪽으로 읽어나가면서, x와 x가 아닌 다른 글자들이 나온 횟수를 각각 셉니다. 처음으로 두 횟수가 같아지는 순간 멈추고, 지금까지 읽은 문자열을 분리합니다.
s에서 분리한 문자열을 빼고 남은 부분에 대해서 이 과정을 반복합니다. 남은 부분이 없다면 종료합니다.
만약 두 횟수가 다른 상태에서 더 이상 읽을 글자가 없다면, 역시 지금까지 읽은 문자열을 분리하고, 종료합니다.
문자열 s가 매개변수로 주어질 때, 위 과정과 같이 문자열들로 분해하고, 분해한 문자열의 개수를 return 하는 함수 solution을 완성하세요.


의사코드

// s 라는 문자열 매개변수를 받는다.
// resultCount, count, noCount 변수 선언
// s 의 첫글자 즉, s[0]의 값을 시작으로 s[0]이랑 s[1]을 비교
// s[0] === s[1] 이면 count++ 해주고 s[2]로 넘어가서 또 비교! 둘이 다르면 noCount++
// count === noCount 일때까지 반복하다가 같아질때 resultCount++ 해주고 같아지는 i까지 문자열요소삭제
// 그리고 다시 위처럼 반복, 더이상 반복할 수 없으면 그대로 resultCount++ 해주고 resultCount 리턴


작성코드

function solution(s) {

    let resultCount = 0; // 리턴값
    let count = 1; // 첫 문자와 같은 문자 수 
    let noCount = 0; // 같지 않은 문자 횟수
    let head = s[0] // 첫글자 기준점
    let tail = s.slice(1); // 첫글자 뒤의 문자열
    if(s.length === 1){ // 재귀 함수를 쓸거라서 매개변수 s 의 길이가 1이 남을때 return 1 -> 무한루프 탈출
      return 1;  
    }
    if(s.length === 0){ // s의 길이가 0일때  return 0 -> 무한루프 탈출
        return 0;
    }
    for(let i = 0; i < tail.length; i++){
        if(head === tail[i]){ // head와 tail[i]가 같은때 count++
          count++;  
        }
        else if(head !== tail[i]){ // 같지 않을때 noCount++
          noCount++;  
        }
        if(count === noCount){ // count와 noCount의 값이 같아질때
          resultCount++; 
          tail = tail.slice(i + 1); // 재귀함수 solution의 매개변수로 들어갈 tail의 값 조작하기
          break; // 우선 resultCount가 올라갔으므로 break키워드로 반복문 나오기.
        }
    }
    if(count !== 1 && count !== noCount){ // tail의 요소들과 head가 다 같아서 반복문을 다 진행하고 나왔을때를 조건문으로 ->  count가 1이 아닐거고, count랑 noCount는 같지 않을것이다.
      return 1;  // 그때도 그 자체를 문자열로 나눠야하기 때문에 return 1;
    }
    return resultCount + solution(tail); // resultCount를 리턴해주면서 solution(tail) 재귀함수도 더해주기.
}

어려웠던 점

재귀함수의 탈출조건을 처음에 tail.length로 써서 문제가 되었다.
재귀함수가 반복되다가 매개변수 s로 'aa'로 들어온다면,
head = 'a', tail = 'a'일 것이다.
그때 재귀함수 무한루프 탈출조건으로 tail.length === 1일때랑 tail.length === 0 일때를 조건으로 넣어두고 계속 왜 안되지? 하며 고민을 많이 했다.
디버거를 돌려 천천히 문제를 찾아보았고, 탈출조건을 잘못썻다는걸 느꼈다.
s.length로 했었어야했다.
if(s.length === 1){
      return 1;  
    }
    if(s.length === 0){
        return 0;
    }

회고

이번 문제는 우선 문제를 이해하기가 조금 어려웠다.
입출력 예를 보면서 이해하려고 해도 뭔 소리지하며 몇번을 보면서 이해했던거같다.
어떤 변수를 선언하고 해야할지를 정하는건 바로 떠올라서 문제가 없었다.
코드를 써보니 매개변수의 첫글자라는 기준점을 하나 잡고 그뒤로 글자들을 비교하며 같을때의 횟수를 세거나 비교해가고 다시 매개변수의 문자열을 잘라서 다시 반복적으로 비교한다는걸 생각해보니,
재귀함수를 써야겠다고 생각이 들어 재귀함수를 써보았다.
재귀함수를 공부하고 문제를 풀어본게 좀 오래전이라 자신이 없었지만, 재귀함수의 주의사항이었던 무한루프 탈출을 생각하며 쓰니 나름 수월했던거 같다.
profile
개발 재밌다

0개의 댓글