반응형
📚 단어 뒤집기 2
문제
문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다.
먼저, 문자열 S는 아래와과 같은 규칙을 지킨다.
- 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져 있다.
- 문자열의 시작과 끝은 공백이 아니다.
- '<'와 '>'가 문자열에 있는 경우 번갈아가면서 등장하며, '<'이 먼저 등장한다. 또, 두 문자의 개수는 같다.
태그는 '<'로 시작해서 '>'로 끝나는 길이가 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>
✍ 접근
- 문제를 보면 알수 있듯이 '<'와 '>'는 번갈아가며 등장하며 '<'가 먼저 등장하며 두 문자의 개수는 같다
- <>
<가 등장했을 때 '>'에 도달할 때까지의 값은 유지된다 ==> 유지시키면 된다 - 숫자 / 소문자
while문으로 연속해서 등장하는 숫자 / 소문자의 위치를 찾아 뒤집은 연속된 숫자 / 소문자로 대치시키면 된다 - 공백
공백은 무시하고 넘어가면 된다
틀린 코드 (시간초과)
import sys
line = list(sys.stdin.readline().strip())
lt = 0
res=""
word = []
while lt < len(line):
if line[lt] == '<':
if word:
res+=word[::-1]
word=[]
while line[lt] != '>':
res+=line[lt]
lt+=1
elif line[lt]== '>':
res+=line[lt]
lt+=1
elif line[lt] == " ":
res+=word[::-1]
word=[]
else:
word.append(line[lt])
pirnt(res)
- 처음에는 while을 돌면서 <> 태그 안 부분은 res=''에 바로 집어넣고 태그 밖 부분은 word라는 빈 배열에 넣은다음에 뒤집어서 res에 집어넣는 식으로 진행했다
- line 자체에 값을 유지시킬 생각을 못하고 계속 복잡한 요소들을 끌어왔다
- 너무 많은 if문을 돌았다.
정답 코드
import sys
wordline = list(sys.stdin.readline().strip())
pointer = 0
while pointer < len(wordline):
if wordline[pointer] == '<':
pointer+=1
while wordline[pointer] != '>':
pointer+=1
pointer+=1
elif wordline[pointer].isalnum():
startP = pointer
while pointer < len(wordline) and wordline[pointer].isalnum():
pointer+=1
tmp = wordline[startP : pointer]
wordline[startP:pointer] = tmp[::-1]
else:
pointer+=1
print("".join(wordline))
- pointer가 wordline의 길이보다 하나 작을 때 while문을 돈다
- while문을 돌면서 wordline[pointer]가 '<'일 때
1. pointer을 하나 더하고
2. wordline[pointer]가 '>'가 아닐 때 중첩된 while문을 돌면서 pointer을 하나씩 증가시켜준다
3. 중첩된 while문을 빠져나올 때 (wordline[pointer])가 == '>' 일 때, pointer을 하나 더 더해준다 - wordline[pointer]가 isalnum()일 때
1. startP라는 변수를 하나 더 만들고 isalnum()이 시작되는 pointer 위치를 집어넣는다.
2. 그 안에서 while문을 돌면서 pointer이 len(wordline)보다 작고, isalnum()일 때, pointer을 하나씩 증가시킨다.
* pointer이 len(wordline)보다 작다는 것을 명시해줘야 한다, 중첩된 while문이기 때문에 이 안에서만 while을 계속 증가시킬 수 있다.
3. 우리가 구한 범위(isalnum이고, 전체 길이를 넘어가지 않는 )의 시작과 끝을 잡아 원래 위치에서 뒤집어준다 - else, '<'도 아니고 isalnum()도 아닐 때, 즉 공백일때
1. pointer을 하나씩 키워준다 - print : ""딱 붙혀서 join시켜준다.
⭐ 배움
- for문과 while문을 사용해야 할 때를 잘 알고 활용하자
- a.isalnum() 숫자 / 알파벳 소문자 == True
- while문이 끝났을 때 시행되는 것은 while의 포지션과 같은 위치에 병렬로 존재한다(for도 마찬가지)
반응형
'🏄♀️ 코딩테스트 > 🐍 Python' 카테고리의 다른 글
[ 백준 17298] ( python ) 오큰수 (0) | 2022.04.06 |
---|---|
[ 백준 10799 ] ( python ) 쇠막대기 (0) | 2022.04.05 |
[ 백준 10866 ] ( python ) 덱 (0) | 2022.04.04 |
[ 백준 1158] ( python ) 요세푸스 문제 (0) | 2022.04.04 |
[ 백준 10845] ( python ) 큐 (0) | 2022.04.03 |