[BOJ] 단어뒤집기2_17413 by JS

개구링·2022년 1월 16일
post-thumbnail

문제

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다.
먼저, 문자열 S는 아래와과 같은 규칙을 지킨다.

알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져 있다.
문자열의 시작과 끝은 공백이 아니다.
'<'와 '>'가 문자열에 있는 경우 번갈아가면서 등장하며, '<'이 먼저 등장한다. 또, 두 문자의 개수는 같다.

태그는 '<'로 시작해서 '>'로 끝나는 길이가 3 이상인 부분 문자열이고, '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다. 단어는 알파벳 소문자와 숫자로 이루어진 부분 문자열이고, 연속하는 두 단어는 공백 하나로 구분한다. 태그는 단어가 아니며, 태그와 단어 사이에는 공백이 없다.

입력

첫째 줄에 문자열 S가 주어진다. S의 길이는 100,000 이하이다.

출력

첫째 줄에 문자열 S의 단어를 뒤집어서 출력한다.

풀이

조건을 두 가지로 나눈다.

  1. 꺼낸 문자 === < 인 경우
    • word에 태그를 담기 시작 (pointer를 증가시키며 쭉쭉 담아준다)
    • 닫는 태그 >를 마지막으로 담으면, answer에 추가 (태그는 따로 뒤집지 않기 때문에 그대로 추가해줌)
    • word를 비워준뒤 break (word에 담기 종료)
  2. 꺼낸 문자 !== < 인 경우
    • word에 뒤집을 문자들을 담기 시작 (마찬가지로 pointer를 증가시키며 쭉쭉 담아준다)
    • 더이상 꺼낼 문자가 없거나 여는 태그 <를 만나면 종료
  • 이후에 word에 문자가 남아있다면, 태그가 아닌 문자열이다.
    (태그는 answer에 추가 후 바로 word를 비워주기 때문)
  • word에서 공백을 제외한 단어들을 뒤집고, answer에 추가해준다.

+
여러모로 심신을 지치게한 문제였다.
특히 입력에서
let input = fs.readFileSync('/dev/stdin').toString().split(' ');으로 한줄입력 받으려 했는데 세상 힘들어지는 Typeerror가 났다는...
그리고 swap에 w를 전달할 때 trim()을 하지 않으면 공백은 물론 개행문자 \n까지 붙어서 들어가버리길래 그냥 trim()을 붙여서해결했다..!

let fs = require('fs');
let input = fs.readFileSync('/dev/stdin') + '';

const inputStr = input.split('');
let answer = '';
let pointer = 0; //입력문자열에서 꺼내볼 문자의 현재 위치(인덱스)
let word = ''; //answer에 담기 전, 태그단위 또는 뒤집을 문자열을 임시로 담아둘 변수

// 태그가 아닌 단어 뒤집는 함수
const swap = (value) => {
  const result = value.split('');

  let lt = 0;
  let rt = result.length - 1;

  while (lt < rt) {
    const temp = result[rt];
    result[rt--] = result[lt];
    result[lt++] = temp;
  }

  return result.join('');
}

while (pointer < inputStr.length) {
  if (inputStr[pointer] === '<') {
    while (true) {
      word += inputStr[pointer++];

      if (inputStr[pointer - 1] === '>') {
        answer += word;
        word = '';
        break;
      }
    }
  } else {
    while (pointer < inputStr.length && inputStr[pointer] !== '<') {
      word += inputStr[pointer++];
    }
  }

  if (word) {
    answer += word.split(' ').map(w => swap(w.trim())).join(' ');
    word = '';
  }
}

console.log(answer);
profile
기록을 취미로

0개의 댓글