배열의 index를 활용한 deque 적용

백준 5430번

QUESTION LINK

배열의 앞 ∙ 뒤를 제거한 다음 마지막에 나오게 된 배열을 보여주면 되는 문제입니다. 처음에는 deque를 구현하고, 이를 사용해서 문제를 해결하고자 했습니다. 하지만, 배열의 앞 ∙ 뒤 만을 제거해주면 되므로, 제거된 부분들이 어디인지만 확인하고, 마지막에 한 번에 제거해주면 된다는 사실을 알고 이를 구현하고자 했습니다.

그리고 이런 식으로 위치가 다 지정된 뒤에는 isLeft 값에 따라 마지막에 만들어진 배열을 Array.reverse()를 통해 뒤집을 지를 결정하면 됩니다.

여기서 처음에 문제가 되었던 부분 중 하나는 배열이 문자열 형식으로 들어온다는 것이었는데, 이는 배열의 앞 ∙ 뒤가 ‘[’, ‘]’로 이루어졌다는 점을 통해, String.substring()으로 앞 ∙ 뒤를 제거하고 ‘,’를 통해서 배열을 직접 만들어주는 것으로 설정했습니다. 그리고 배열이 비어있는 경우는 변환 시 ['']와 같은 형태가 되어, 이를 구분 짓는 방법도 추가해주었습니다.

const [_, ...commands] = fs
  .readFileSync(filePath)
  .toString()
  .trim()
  .split("\n");
const resultArray = [];

commands.forEach((commandLine, index) => {
  if (index % 3 !== 0) return;

  const arrayString = commands[index + 2];
  const command = commandLine.split("");
  const array = arrayString.substring(1, arrayString.length - 1).split(",");
  // 배열 문자열의 앞 뒤를 자르고 ','로 구분된 배열을 만듬
  if (!array[0].length) array.pop();
  // 빈 배열의 문자열인 경우 실제로 배열이 비어있게 만듬

  ...

그리고 위에서 하고자 했던 방법과 같이, 명령어에 따라 ‘R’인 경우는 뒤집혔다는 것을 나타내기 위해 isLeft값을 기존 값에서 바꾸고, ‘D’인 경우에는 isLeft의 상태에 따라 왼쪽 값을 늘리거나 또는 오른쪽 값을 줄입니다.

여기서 에러를 판단하는 상황이 중요했는데, 이는 왼쪽, 오른쪽이 삭제되면서 점점 만나고 왼쪽이 오른쪽보다 커질 때 더 이상 삭제할 것이 없다고 판단하는 것으로 처리했습니다.

그리고 여기서 한 가지 더 예외 처리를 해주어야 할 것은, 에러가 발생하는 타이밍이 ‘D’를 입력했을 경우라서 배열이 비어있다고 무조건 에러를 보여주어선 안 됩니다.

  ...

  let isLeft = true;
  let left = 0;
  let right = array.length;
  let isError = false;

  command.forEach((word) => {
    if (isError) return;
    // 에러라면 더 이상 진행하지 않음
    if (word === "R") {
    // isLeft값만을 계속 바꿔주어 어느쪽에서 삭제를 해야하는 지 결정함
      isLeft = !isLeft;
    } else {
    // isLeft 값에 따라 삭제할 곳을 정함
      isLeft ? (left += 1) : (right -= 1);
      if (left > right) isError = true;
      // 왼쪽이 오른쪽보다 커지는 경우 더 이상 삭제할 것이 없으므로 에러를 보여줌
    }
  });

  if (isError) {
    resultArray.push("error");
    return;
  }

  const curResult = array.slice(left, right);
  // 남아있는 배열들을 가져옴

  if (!isLeft) curResult.reverse();
  // 거꾸로 된 상활일 경우 한 번 뒤집어줌
  resultArray.push(curResult);
});

const result = resultArray
  .map((value) => {
    if (value === "error") return value;
    return `[${value.join(",")}]`;
    // 배열 문자열로 다시 만들어줌
  })
  .join("\n");

console.log(result);

이 문제의 경우, 예외 처리를 해주는 상황에서 계속 문제를 틀리게 됐습니다. 특히, 처음에 ‘D’를 입력했을 때 비어있는 경우 에러를 보여주어야 하는데, 배열이 비어있으면 무조건 에러를 보여주는 것으로 처리를 하는 바람에 문제가 되었습니다. 더불어, 빈 배열을 입력받는 경우, 이를 실제 배열로 바꾸면 [’’]의 형태가 되는데, 이를 그대로 처리하려다보니 문제가 되었습니다. 올바른 처리를 위해서는 처음에 설정을 할 때 확실하게 예외 처리를 하는 것이 중요하다는 걸 느꼈습니다.