Notice
Recent Posts
Recent Comments
Link
관리 메뉴

윤일무이

[JavaScript] 프로그래머스 코딩테스트 레벨 1 : 문자열 나누기 본문

⚙️ 코딩테스트

[JavaScript] 프로그래머스 코딩테스트 레벨 1 : 문자열 나누기

썸머몽 2023. 6. 5. 02:44
728x90

📌  문제

문자열 s가 입력되었을 때 다음 규칙을 따라서 이 문자열을 여러 문자열로 분해하려고 합니다.

  • 먼저 첫 글자를 읽습니다. 이 글자를 x라고 합시다.
  • 이제 이 문자열을 왼쪽에서 오른쪽으로 읽어나가면서, x와 x가 아닌 다른 글자들이 나온 횟수를 각각 셉니다. 처음으로 두 횟수가 같아지는 순간 멈추고, 지금까지 읽은 문자열을 분리합니다.
  • s에서 분리한 문자열을 빼고 남은 부분에 대해서 이 과정을 반복합니다. 남은 부분이 없다면 종료합니다.
  • 만약 두 횟수가 다른 상태에서 더 이상 읽을 글자가 없다면, 역시 지금까지 읽은 문자열을 분리하고, 종료합니다.

문자열 s 매개변수로 주어질 , 과정과 같이 문자열들로 분해하고, 분해한 문자열의 개수를 return 하는 함수 solution 완성하세요.

📌  제한사항

  • 1 ≤ s의 길이 ≤ 10,000
  • s 영어 소문자로만 이루어져 있습니다.

📌  풀이

알아야 하는 것

  • str.slice(시작 인덱스[, 끝 인덱스]) : 시작 인덱스부터 끝 인덱스 직전까지 문자열 일부를 추출해 새로운 문자열로 반환한다. 

구할 것

첫 글자 x의 수와 x가 아닌 다른 글자의 수가 같을 때 지금까지 읽은 문자열을 분리하고, 나머지 부분도 동일한 원리로 문자열을 분리한다.

남은 부분이 없거나, 두 수가 다른 상태에서 더 카운트할 글자가 없다면 마찬가지로 지금까지 읽은 부분만 분리해 종료해야 한다.

 

예를 들어 s = "banana" 라면, 첫 글자 b와 다음 글자 a의 수가 1과 1로 동일해 분리해준다.

nana가 있을 때, 첫 글자 n과 다음 글자 a의 수가 1과 1로 동일해 분리되고, 다음 na도 똑같이 분리되어 총 3이 반환된다.

 

또 "abracadabra"를 예시로 들자면, 첫 글자 a와 다음 글자 b의 수가 1과 1로 동일해 분리된다.

ra, ca, da, br도 모두 각각의 첫 글자와 그 다음 글자의 수가 1과 1로 동일하여 분리되면 a만 남게 된다.

이 경우 a도 지금까지 읽은 문자열로 분류해 분리되기 때문에 총 ab - ra - ca - da - br - a 6을 반환하게 된다.

 

이를 위해 첫 글자 x의 수와 x가 아닌 수를 구할 변수 countX, countNotX를 선언해주었다.

그리고 최종적으로 분해된 문자열의 개수를 반환할 answer을 선언했다.

 

for문으로 문자열 s를 순회할 때, 첫 글자 포함 다음 글자가 첫 글자와 같을 경우 countX 에 1을 더해주고, 그렇지 않을 경우에는 countNotX에 1을 더해주었다.

 

이후 두 변수의 수가 같을 때, 지금까지 읽은 문자열을 빼고 그 다음 문자열부터 새로 시작해야 하기 때문에 slice 메소드를 사용해 지금까지 읽은 문자열까지를 잘라주었다. slice 메소드의 시작 인덱스를 생략하면 처음부터 자르게 되고, i 까지 잘라가게 된다.

 

이렇게 자르게 되면 분해된 문자열이 1 증가하므로 answer에 1을 더해주고, countX와 countNotX는 0으로 초기화 된다. 그리고 다음 반복문에서 0부터 시작하게 하기 위해 i를 -1로 설정한다. (반복문이 다 끝나갈 때 1을 더해주니까, -1로 설정하면 1을 더한 상태로 for문에 0으로 시작할 수 있다.)

 

여기서 문제였던 건 두 번째 예시처럼 a가 혼자 똑 떨어지는 경우였다.

마지막 조건문을 추가하지 않을 경우, a처럼 카운트되지 않은 문자는 포함되지 않아 오류가 발생했다.

해서 문자열이 다 분리된 후에도 혼자 남아 있는지 length로 확인하고, 혼자 남아 있는 경우에도 answer += 1 로 추가해주었다.

function solution(s) {
  let countX = 0;
  let countNotX = 0;
  let answer = 0;

  for (let i = 0; i < s.length; i++) {
    if (s[0] === s[i]) {
      countX += 1;
    } else {
      countNotX += 1;
    }
    if (countX === countNotX) {
      s = s.slice(i + 1);
      answer += 1;
      countX = 0;
      countNotX = 0;
      i = -1;
    }
  }
  if (s.length > 0) {
    answer += 1;
  }
  return answer;
}

 

 

 

728x90