C언어 백준 문제 풀이

백준 1152번 단어의 개수

20bill 2021. 10. 22. 15:30
728x90

1152번: 단어의 개수 (acmicpc.net)

 

1152번: 단어의 개수

첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 공백 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열

www.acmicpc.net

 

 

문제 요약: 첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어지면 공백을 기준으로 단어의 개수를 카운트하고 출력한다. 문자열의 길이는 1,000,000을 넘지 않으며 한 단어가 여러 번 등장하면 등장한 횟수만큼 모두 센다. 

 

 

문제 풀이: 이 문제를 보자마자 1학년 때 C언어 수업 때 배운 토큰 분리가 떠올랐다. 그냥 말 그대로 strtok함수를 이용해서 공백을 기준으로 토큰을 분리하고 루프가 한번 돌아갈 때마다 count를 해서 최종 값을 출력하면 된다. 문제를 풀면서 처음에 문자열 입력을 scanf로 받았다. 하지만 디버깅 결과 단어의 수를 아무리 많이 입력해도 1이 나왔고, 혼자 고민하며 리서치를 한 후에야 이유를 알게 되었다. scanf는 공백, 줄 바꿈, EOF를 만나면 입력을 종료한다는 것을 말이다. 그래서 문장을 입력받았을 때, 첫 단어를 쓰고 공백을 넣게 되면 바로 입력이 종료되어서 단어의 개수는 항상 1이 나왔던 것이다. 그래서 공백까지 입력이 가능한 gets함수를 쓰기로 했다. 한번 더 정리할 겸, scanf와 gets함수를 정리해보겠다. 

scanf: 공백, 줄 바꿈 또는 EOF를 만나면 입력을 종료한다. 

gets: 공백을 입력 문자열의 일부로 간주하고 줄 바꿈이나 EOF를 만나면 입력을 종료한다.

토큰을 분리할 때, 반복문 안에 있는 strtok(NULL, " ")이 부분을 왜 str이 아닌 NULL을 집어넣냐고 궁금해 할 수도 있다. 나도 처음에는 그렇게 생각했었다. str이 아닌 NULL이 들어가는 이유는 만약에 result가 문자열 끝에 존재하는 NULL을 만나지 않고 공백을 만났다면(조건문) str이 아닌 NULL을 넣음으로써 strtok가 잘랐던 부분이 어디까지인지 기억하기 때문에 그다음 문자를 분리할 수 있다. 만약에 str을 넣게 된다면 처음 문자만 계속 분리된기 때문에 주의한다. 또한 strtok 함수는 문자열을 새로 생성해서 반환하는 것이 아닌, 기존에 존재하는 원본 문자열에서 분리하는 부분에 NULL문자를 채운 뒤 잘린 문자열의 포인터를 반환하는 것이기 때문에 내용이 변경되니 사용에 주의한다.  

 

 

 

 

 

http://colorscripter.com/s/GgGRwty

 

공유된 코드 - Color Scripter

저작권자 : inryureal@tistory.com 삭제 요청 코드 설명 : C언어 백준 1152번 단어의 개수

colorscripter.com

 

728x90