[js] 문자열 여러 번 뒤집기 (lv.0, 정답률 80%)

sookyoung.k·2024년 5월 2일
0
post-thumbnail

문자열 my_string과 이차원 정수 배열 queries가 매개변수로 주어집니다. queries의 원소는 [s, e] 형태로, my_string의 인덱스 s부터 인덱스 e까지를 뒤집으라는 의미입니다. my_string에 queries의 명령을 순서대로 처리한 후의 문자열을 return 하는 solution 함수를 작성해 주세요.

제한사항

  • my_string은 영소문자로만 이루어져 있습니다.
  • 1 ≤ my_string의 길이 ≤ 1,000
  • queries의 원소는 [s, e]의 형태로 0 ≤ s ≤ e < my_string의 길이를 만족합니다.
  • 1 ≤ queries의 길이 ≤ 1,000

😭 나의 풀이

function solution(my_string, queries) {
    let splitStr = my_string.split('');
    
    for (let [s, e] of queries) {
        let middle = splitStr.slice(s, e + 1).reverse();
        splitStr.splice(s, e - s + 1, ...middle);
    }
    return splitStr.join('');
}

와 이거 진짜 어려웠다 ㅠㅠ 배열 메서드를 제대로 알아야 정확하게 풀 수 있는 문제였다. 이거 때문에 엄청 고생함... 그러니까 공부를 잘 해둬야 하는 것임!

  • 먼저 문자열을 배열로 쪼갠다.
  • 주어진 queries를 [s, e]에 구조분해 할당하여 순환한다.
  • 반전 시킬 문자를 slice() 메서드를 통해 잘라낸 후(s부터 e까지, 즉 splitStr.slice(s, e + 1)), reverse() 메서드를 통해 반전시킨다. 그리고 이 결과를 middle 변수에 할당한다.
    - 이때, 원본 배열을 손상시키지 않도록 주의한다 😭 초반 오류는 여기서 다 났음... splice()는 원본을 손상시킨다. 바로 다음에 쓸 것임.
  • 그리고 splice() 메서드를 통해 s부터 e까지의 인덱스를 middle로 바꿔준다.
    - 두 번째 오류는 여기서 났다... splice() 메서드의 경우 두 번째 인자가 인덱스를 의미하는 것이 아닌 삭제할 요소의 숫자를 의미한다. 때문에 시작점과 끝점 사이에 있는 요소의 수, 즉 e - s + 1을 넣어줘야 올바르게 제거하고 새로운 요소를 추가할 수 있다.
  • 그리고 배열을 다시 문자열로 합쳐서 답을 반환한다.

🤓 기억하고 넘어갈 것들

slice()splice()의 차이

  1. slice()는 원본 배열/문자열을 변경하지 않는다. 하지만 splice()는 원본 배열을 변경한다**.
  2. 따라서 slice()는 선택된 요소/문자들을 포함하는 새로운 배열/문자열을 반환한다. splice()는 제거된 요소들을 포함하는 새 배열을 반환한다.
  3. slice() → 배열/문자열의 특정 부분 복사할 때 사용 vs. splice() → 배열의 요소를 제거하거나 추가할 때 사용된다.
  4. slice()만 배열, 문자열 모두 사용 가능하다.

splice() 메서드의 두 번째 인자

두 번째 인자는 삭제할 요소의 '수'를 지정하는 것이지, 인덱스를 뜻하는 것이 아니다!!

array.splice(start, deleteCount, item1, item2, ...)

→ 변경을 시작할 인덱스(start)부터 제거할 요소의 수(deleteCount)를 지정하여 삭제한다. (만약 deleteCount를 0으로 설정하면 어떠한 요소도 제거하지 않고 새 요소를 추가할 수 있다.)
item1, item2, ...는 배열에 추가될 요소들을 의미한다. 추가하지 않는다면 요소를 제거하기만 할 수 있다.

slice()

array.slice(start, end) / string.slice(start, end)

slice()의 두 번째 인자는 추출을 끝내고자 하는 인덱스를 뜻한다 (해당 인덱스의 요소는 포함 x)

😊 다른 풀이 1

function solution(my_string, queries) {
    let str = my_string.split('');
  	queries.forEach(([start, end]) => {
    const changeStr = str.slice(start, end + 1);
    str.splice(start, changeStr.length, ...changeStr.reverse());
  });
  return str.join('');
}

여기서는 for...of가 아니라 forEach를 통해서 순환한다는 점이 다른 점임.

😋 다른 풀이 2

function solution(my_string, queries) {
    const str = [...my_string];
    queries.forEach(([s,e]) => {
        while(s < e) {
            [str[s], str[e]] = [str[e], str[s]];
            s++; e--;
        }
    })
    return str.join("");
}
  • 문자열을 분해하여 배열 str에 저장
  • 문자열을 뒤집는다. 각 요소 s, e에 대해 루프를 사용하여 s 인덱스에 있는 문자와 e 인덱스에 있는 문자를 서로 바꾼다. 그 후 s를 1 증가시키고 e를 1 감소시켜서 범위를 좁혀간다. 이 작업은 s가 e보다 작거나 같을 때까지 계속된다.
  • 결과 반환

오 이러한 풀이는 또 신박하고... 신기하다... 하 기본적인 것도 제대로 공부가 안 되어있는 나 자신에게 반성하고 감.

profile
영차영차 😎

0개의 댓글