문제 설명
문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다.
먼저, 문자열 S는 아래와과 같은 규칙을 지킨다.
- 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져 있다.
- 문자열의 시작과 끝은 공백이 아니다.
- '<'와 '>'가 문자열에 있는 경우 번갈아가면서 등장하며, '<'이 먼저 등장한다. 또, 두 문자의 개수는 같다.
태그는 '<'로 시작해서 '>'로 끝나는 길이가 3 이상인 부분 문자열이고, '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다. 단어는 알파벳 소문자와 숫자로 이루어진 부분 문자열이고, 연속하는 두 단어는 공백 하나로 구분한다. 태그는 단어가 아니며, 태그와 단어 사이에는 공백이 없다.
입력
첫째 줄에 문자열 S가 주어진다. S의 길이는 100,000 이하이다.
출력
첫째 줄에 문자열 S의 단어를 뒤집어서 출력한다.
해결법
1. 입력받은 문자열을 먼저 리스트로 변환
2. 리스트를 순회하면서 '<'이 나오는 조건문에서 '>'가 나올 때까지 이터레이터를 돌리기
3. 리스트를 순회하면서 숫자거나 문자열이 나오면 이터레이터가 S의 길이를 초과하지 않는 선에서 해당 구간을 뒤집은 문자열로 교체하기
4. 리스트를 순회하면서 공백이라면 그냥 이터레이터를 돌리기
코드
S = list(input())
i=0
start = 0
while(i < len(S)):
if(S[i] == '<'):
i+=1
while(S[i] != '>'): # 닫는 태그 나올 때까지 i증가 시키면서 돌기
i+=1
i+=1 # 닫는 태그후에 i 증가 시킴
elif(S[i].isalnum()): # 숫자거나 문자열이면
start = i
while(i < len(S) and S[i].isalnum()): # 계속 숫자거나 문자열이면 or 모든 문자열을 다 돌았으면
i+=1
tmp = S[start:i] # 해당 구간을 거꾸로 돌린 문자열로 교체
tmp.reverse()
S[start:i] = tmp
else: # 공백이라면 i만 증가시킴
i += 1
print("".join(S))
깨달은 점
1. out of range
오류를 피하기 위해서 i < len(word)
도 고려하자
이터러블한 객체를 끝까지 돌 때의 조건을 나는 지금까지 거의 i != len(lst)
로만 사용했다.
하지만, 만약 i
를 사용해서 리스트의 값을 비교해야 하는 문이 해당 조건문에 같이 들어가게 된다면 IndexError: list index out of range
의 에러가 나올 수밖에 없다.
그럴 때, i < len(word)
를 사용하면, out of range
오류가 나지 않으면서 끝까지 순회하도록 할 수 있다는 것을 알아두자.
한 가지 더, 위와 같은 상황에선 i < len(word)
를 다른 비교문보다 먼저 작성하자. 조건문 안에서 비교문을 먼저 실행함으로써 똑같이 out of range
가 발생할 수 있기 때문!
2. 순차적으로 순회하는 이터레이터, i
를 잘 활용하자
문자열의 길이만큼 반복을 해야 하는 건 알았는데 그것을 for문으로만 계속 한정지어서 생각하다 보니 해결방법이 잘 떠오르지 않았다.
하지만 또 다시 생각해 보면, 이 문제는 for문이나 while문이나 별 차이가 없다.
단지, 반복문의 이터레이터를 얼마나 잘 사용했느냐가 관건인 문제가 아닌가 싶다.
이터러블 객체의 끝까지 순차적으로 순회하는 이터레이터인 i
를 조건에 따라서 일정 구간 잘 움직이면서 답을 찾아가는 문제인 것이다.
그래도 for문과 while문을 언제 사용하는 것이 적절한지에 대해서도 알아보자.
3. for문과 while문의 차이점!
for문 : 구하고자 하는 값이 정확한 조건이 있는 경우, 가독성이 좋다.
while문 : 구하고자 하는 값이 정확한 조건을 정확히 모를 경우 즉, 유동적인 경우, 가독성은 안좋을 수 있다.
'알고리즘 공부 > coding test' 카테고리의 다른 글
백준 10799 [쇠막대기] (0) | 2022.09.16 |
---|---|
백준 1931 [회의실 배정] (0) | 2022.05.20 |
백준 20115 [에너지 드링크] (0) | 2022.05.20 |
백준 11399 [ATM] (0) | 2022.05.18 |
백준 2217[로프] (0) | 2022.05.17 |