본문 바로가기
👩‍💻 Programming/Coding Test 문제 풀이

[Baekjoon] 17413 단어 뒤집기 2(파이썬/자바스크립트/NodeJS)

by codingBear 2022. 12. 25.
728x90
반응형

이번 문제는 아래 링크에서 풀어볼 수 있습니다.

 

17413번: 단어 뒤집기 2

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다. 먼저, 문자열 S는 아래와과 같은 규칙을 지킨다. 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져

www.acmicpc.net


문제

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다.

먼저, 문자열 S는 아래와과 같은 규칙을 지킨다.

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

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

입력

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

출력

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

예제 입력 1

baekjoon online judge

예제 출력 1

noojkeab enilno egduj

예제 입력 2

<open>tag<close>

예제 출력 2

<open>gat<close>

예제 입력 3

<ab cd>ef gh<ij kl>

예제 출력 3

<ab cd>fe hg<ij kl>

예제 입력 4

one1 two2 three3 4fourr 5five 6six

예제 출력 4

1eno 2owt 3eerht rruof4 evif5 xis6

예제 입력 5

<int><max>2147483647<long long><max>9223372036854775807

예제 출력 5

<int><max>7463847412<long long><max>7085774586302733229

예제 입력 6

<problem>17413<is hardest>problem ever<end>

예제 출력 6

<problem>31471<is hardest>melborp reve<end>

예제 입력 7

<   space   >space space space<    spa   c e>

예제 출력 7

<   space   >ecaps ecaps ecaps<    spa   c e>

정답 코드

답안 1
파이썬 Ver.
import sys


def answer1():
    s = list(sys.stdin.readline().rstrip())
    
    i = 0
    start = 0
    
    while i < len(s):
        if s[i] == '<': # 열린 괄호를 만나면 i 1증가
            i += 1
            while s[i] != '>': # 닫힌 괄호를 만날 때까지 i 1증가
                i += 1
            i += 1 # 닫힌 괄호를 만난 후 i 1증가
        elif s[i].isalnum():
            start = i
            while i < len(s)  and s[i].isalnum():
                i += 1
            tmp = s[start:i] # 태그가 아닌 단어를 뒤집는다.
            tmp.reverse()
            s[start:i] = tmp
        else: # 공백일 경우 i 1증가
            i += 1
    
    return ''.join(s)


print('answer1', answer1())


자바스크립트/NodeJS Ver.

const fs = require('fs');
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';
let input = fs.readFileSync(filePath).toString().trim();

const solution1 = (data) => {
    const isAlpha = (s) => {
        if (data[i] >= 'a' && data[i] <= 'z') return true;
        return false;
    };
    const isNum = (s) => {
        if (data[i] >= '0' && data[i] <= '9') return true;
        return false;
    };

    let result = data.split('');
    let i = 0;
    let start = 0;

    while (i < result.length) {
        if (result[i] === '<') {
            i++;
            while (result[i] !== '>') i++;
            i++;
        } else if (isAlpha(result[i]) || isNum(result[i])) {
            start = i;
            while (
                i < result.length &&
                (isAlpha(result[i]) || isNum(result[i]))
            )
                i++;
            let tmp = result.slice(start, i).reverse();
            for (let j = 0; j < tmp.length; j++) {
                result[start] = tmp[j];
                start++;
            }
        } else i++;
    }

    return result.join('');
};

console.log('solution1');
console.log(solution1(input));
답안 2
파이썬 Ver.
import sys


def answer2():
    s = sys.stdin.readline().rstrip()
    
    isTag = False
    result = ''
    stack = ''

    for c in s:
        if c == '<':
            isTag = True
            result += stack[::-1]
            stack = ''
            result += c
            continue
        elif c == ">":
            isTag = False
            result += c
            continue
        elif c == ' ':
            result += stack[::-1] + ' '
            stack = ''
            continue
            
        if isTag:
            result += c
        else:
            stack += c

    return result

print('answer2', answer2())


자바스크립트/NodeJS Ver.

const fs = require('fs');
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';
let input = fs.readFileSync(filePath).toString().trim();

const solution2 = (data) => {
    const string = data.split('');

    let isTag = false;
    let result = '';
    let stack = '';

    for (let i of string) {
        if (i === '<') {
            isTag = true;
            result += stack.split('').reverse().join('');
            stack = '';
            result += i;
            continue;
        } else if (i === '>') {
            isTag = false;
            result += i;
            continue;
        } else if (i === ' ') {
            result += stack.split('').reverse().join('') + ' ';
            stack = '';
            continue;
        }

        isTag ? (result += i) : (stack += i);
    }

    if (stack) result += stack.split('').reverse().join('');

    return result;
};

console.log('solution2');
console.log(solution2(input));
답안 3
파이썬 Ver.
import sys


def answer3():
    s = list(sys.stdin.readline().rstrip())
    
    isTag = False
    word = ''
    result = ''

    for c in s:
        if not isTag: # 태그 내 문자가 아니라면 뒤집어서 출력
            if c == '<':
                isTag = True
                word += c
            elif c == ' ': # 탐색하는 문자가 공백이라면
                word += c
                result += word
                word = ''
            else:
                word = c + word # 문자 거꾸로 붙여넣기
        else: # 태그 내 문자라면 그대로 출력
            word += c
            if c == '>':
                isTag = False
                result += word
                word = ''
    
    return result + word
                  
print('answer3', answer3())


자바스크립트/NodeJS Ver.

const fs = require('fs');
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';
let input = fs.readFileSync(filePath).toString().trim();

const solution3 = (data) => {
    const string = data.split('');

    let isTag = false;
    let result = '';
    let stack = '';

    for (let i of string) {
        if (!isTag) {
            if (i === '<') {
                isTag = true;
                stack += i;
            } else if (i === ' ') {
                stack += i;
                result += stack;
                stack = '';
            } else stack = i + stack;
        } else {
            stack += i;
            if (i === '>') {
                isTag = false;
                result += stack;
                stack = '';
            }
        }
    }

    return result + stack;
};

console.log('solution3');
console.log(solution3(input));
답안 4
파이썬 Ver.
import sys


def answer4():
    s = sys.stdin.readline().rstrip()
    
    stack = []
    result = []

    for i in range(len(s)):
        if s[i] == '>': # 닫힌 괄호가 나오면
            stack.append(s[i])
            result.append(''.join(stack))
            stack = []
        elif s[i] == '<' and stack: # 열린 괄호가 나왔는데 stack에 요소가 있다면
            stack.reverse() # stack을 뒤집어서 추가
            result.append(''.join(stack))
            stack = [s[i]]
        elif s[i] == ' ' and '<' not in stack: # 공백 문자인데 괄호 밖이라면
            stack.reverse() # stack을 뒤집어서 추가
            result.append(''.join(stack))
            result.append(' ')
            stack = []
        else:
            stack.append(s[i])
    
    if stack: # 아직 stack에 요소가 남아 있다면 뒤집어서 추가
        stack.reverse()
        result.append(''.join(stack))
    
    return ''.join(result)
  
print('answer4', answer4())


자바스크립트/NodeJS Ver.

const fs = require('fs');
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';
let input = fs.readFileSync(filePath).toString().trim();

const solution4 = (data) => {
    const string = data.split('');

    let result = [];
    let stack = [];

    for (let i of string) {
        if (i === '>') {
            stack.push(i);
            result.push(stack.join(''));
            stack = [];
        } else if (i === '<' && stack.length) {
            result.push(stack.reverse().join(''));
            stack = [i];
        } else if (i === ' ' && !stack.includes('<')) {
            result.push(stack.reverse().join('') + ' ');
            stack = [];
        } else stack.push(i);
    }

    if (stack.length) result.push(stack.reverse().join('') + ' ');

    return result.join('');
};

console.log('solution4');
console.log(solution4(input));

문제 풀이

 자료구조 중 스택을 이용해서 풀 수 있는 문제이다. 내가 구현하고자 했던 로직과 가장 유사한 답안 3을 기준으로 설명하겠다.

 우선 for 반복문으로 입력 받은 문자열을 탐색하면서 탐색하는 값이 태그 내 문자가 아닌 경우 조건문에 따라 3가지 동작을 한다. 탐색하는 문자가 열린 괄호('<')일 경우 isTag를 True로 변경하고 단어에 탐색하는 문자를 더한다. 공백일 경우 word 및 result에 그대로 붙이고 word를 초기화한다. 탐색하는 문자가 문자 혹은 숫자라면 word에 거꾸로 붙여넣는다. 탐색하는 문자가 태그 내 문자라면 거꾸로가 아니라 그대로 word에 붙여넣고 닫힌 괄호('>')가 나올 경우 isTag를 False로 변경한 뒤 이때까지 쌓은 word를 result에 붙여넣고 word를 초기화한다.


함께 보기

https://hongcoding.tistory.com/62

 

[백준] 17413 단어 뒤집기2 (Python 파이썬)

www.acmicpc.net/problem/17413 17413번: 단어 뒤집기 2 문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다. 먼저, 문자열 S는 아래와과 같은 규칙을 지킨다. 알파벳 소문자('a'-'z'), 숫자('0'-'9'),

hongcoding.tistory.com

https://my-coding-notes.tistory.com/401

 

[🥈3 / 백준 17413 / 파이썬] 단어 뒤집기 2

17413번: 단어 뒤집기 2 문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다. 먼저, 문자열 S는 아래와과 같은 규칙을 지킨다. 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자(''

my-coding-notes.tistory.com

https://velog.io/@bye9/%EB%B0%B1%EC%A4%80%ED%8C%8C%EC%9D%B4%EC%8D%AC-17413-%EB%8B%A8%EC%96%B4-%EB%92%A4%EC%A7%91%EA%B8%B02

 

[백준/파이썬] 17413 단어 뒤집기2

https://www.acmicpc.net/problem/17413구현tag가 시작된 경우는 정상적으로 출력하고 >를 만난 순간 tag=False를 통해 뒤집어서 출력해간다. 중간에 공백을 만나면 공백을 더한 값을 출력하고 word를 초기화시

velog.io

https://m.blog.naver.com/chanmuzi/222846128285

 

17413 : 단어 뒤집기 2 [구현](Python)

단어 뒤집기 2 문제 문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다. 먼저, 문자열 S는 ...

blog.naver.com

https://it-neicebee.tistory.com/43

 

[Python] isalpha(), isalnum() 함수

isalpha() 문자열이 영어 혹은 한글로 되어있으면 참 리턴, 아니면 거짓 리턴. text = "!#$$!@$!!!!!!!!@$#231421234네123^&^#$#이!#12313_+{스" text1 = "네이스" text2 = "123123" text3 = "!@#$" check = "" print(text1.isalpha()) print

it-neicebee.tistory.com

 

728x90
반응형

댓글