사용 언어: python 3.7.4
문제
영어 대소문자와 띄어쓰기만으로 이루어진 문자열이 주어진다. 이 문자열에는 몇 개의 단어가 있을까? 이를 구하는 프로그램을 작성하시오. 단, 한 단어가 여러 번 등장하면 등장한 횟수만큼 모두 세어야 한다.
입력
첫 줄에 영어 대소문자와 띄어쓰기로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 띄어쓰기 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열의 앞과 뒤에는 공백이 있을 수도 있다.
출력
첫째 줄에 단어의 개수를 출력한다.
입력받은 문자열을 공백으로 쪼개서 리스트로 만들면, 리스트의 원소의 개수가 원하는 답이라고 생각했다.
하지만 문제에서 문자열 앞 뒤로 공백이 있을 수도 있다는 조건을 놓쳐서 틀렸다.
string = input()
print(len(string.split(' ')))
문자열 앞 혹은 뒤에 공백이 있을 경우, 리스트 원소로 ''(빈 문자)가생기므로 ''를 제거하는 코드가 필요했다.
for문과 리스트의 remove 메소드를 사용하면 잘 제거될 거라고 생각했다.
하지만 remove한 원소의 바로 다음 index의 원소는 확인되지 않고 넘어간다는 사실을 몰랐어서, 공백이 들어오면 틀린다는 것을 알게 되었다.
string = input()
str_list = string.split(' ')
for item in str_list:
if item == '':
str_list.remove('')
#print(str_list)
print(len(str_list))
▽추가설명▽
"a a b c"라는 문자열에서 'a'를 모두 지우고 싶다고 하자.
코드처럼 remove('a')를 하면 첫번째 'a'는 제거된다.
하지만, 첫번째 'a'를 제거하면 리스트의 index가 재배치되어 두번째 'a'의 인덱스가 0이 된다. 그러면 다음으로 검사할 인덱스가 1인 원소는 b가 되고, 두번째 'a'는 검사하지 않고 넘어가기 때문에 제거하지 못한다. 결국 리스트를 출력해보면 첫번째 'a'만 제거해서 ['a', 'b', 'c']가 나온다.
마찬가지로 공백인 문자열이 들어왔을 때, 공백으로 쪼갠 리스트는 ['', ''] 이다. remove('')를 하면 첫번째 ''는 제거하지만 두번째 ''는 제거하지 않기 때문에 최종적으로 리스트의 길이가 0이 아니고 1이므로 틀리는 것이다.
while문을 통해 해결했다.
또 다른 방법으로, 특정 문자열과 같지 않은 모든 문자로 다시 리스트를 만드는 방법도 있었다.
두 방법 모두 정답이고, 백준에서 채점했을 때 걸린 시간은 똑같았다. 하지만, 메모리 사용량으로 비교해봤을 때, while문 방법은 36368 KB, 리스트 생성 방법은 37736 KB 였다.
따라서 while문 방법이 메모리를 더 적게 차지해서 좋다고 판단했다.
while문과 리스트의 remove 메소드 사용
string = input()
str_list = string.split(' ')
while '' in str_list:
str_list.remove('')
print(len(str_list))
string = input()
str_list = string.split(' ')
str_list = [i for i in str_list if i != '']
print(len(str_list))
correct
메모리 | 시간 | 코드길이 |
---|---|---|
36368 KB | 92 ms | 115 B |
O(N)
특정 문자로 문자열을 쪼개는 방법: string.split('특정 문자')
특정 문자를 문자열에서 제거하는 방법:
(1) string.remove('특정 문자')
※ remove 메소드는 문자열에서 처음 등장하는 특정 문자만 제거하므로, 특정 문자를 모두 지우고 싶으면 반복문(while 추천)을 사용해야 한다.
(2) 특정 문자를 포함하지 않는 리스트를 다시 만드는 것도 특정 문자를 제거한 것과 같은 효과를 볼 수 있다.
for문과 remove 메소드를 사용했을 때 특정문자가 완전히 제거되지 않는 것을 보고 처음에는 출력 프로그램을 의심했다. 하지만 역시 코드가 문제인 거니까 괜히 출력 프로그램을 의심하는 1초의 시간도 낭비하지 말자.