#include <stdio.h>
#include <string.h>
int main(void)
{
char str[1000000 + 1];
int cnt = 0, i, len;
gets(str);
len = strlen(str);
for (i = 0; i<len; i++)
if(str[i] == ' ' && i !=0 && i != len-1)
cnt++;
printf("%d", len==1 && *str == ' ' ? cnt : cnt + 1);
return 0;
}
풀이1
- 최대 1000000 길이의 문자열 입력받음
- 문자열을 이루는 요소가 공백일 때, 첫번째나 마지막에 오지 않는다면 카운트
- 예외: 입력값이" "일때는 단어수는 0이 되어야 함. 따라서 출력문을 단순 cnt+1가 아닌 삼항으로 조건처리해야한다
- 문자열을 입력받을 때는 scanf("%[^\n]", str)을 사용하거나 gets를 사용
- 단 gets의 경우 C11들어서 라이브러리에서 삭제되었기 때문에
C11표준 컴파일러에서는 사용할 수 없다고 한다..(C99 채점환경에서는 동작함) - 아마 fgets를 사용하거나 정규표현식을 살짝 섞은 scanf를 사용해야할 듯
- 단 gets의 경우 C11들어서 라이브러리에서 삭제되었기 때문에
더보기
더보기
# C11에서 gts()함수가 라이브러리에서 삭제됐음, 즉 C11표준이 적용되는 컴파일러에서는 gets()함수를 사용할 수 없습니다.
# gets_s는 비주얼 스튜디오에서 gets()의 대체함수로 제공되었습니다. 다만 표준은 아니기 때문에 채점환경에서는 사용할 수 없습니다. 비주얼 스튜디오에서만 동작하는 함수이기 때문에 백준에서는 버전을 C11이전으로 해주시면 gets는 사용가능하지만 gets_s는 사용 불가능합니다. 비주얼스튜디오에서는 gets_s잘 동작!
출처: https://jhnyang.tistory.com/117 [양햄찌가 만드는 세상]
#include <stdio.h>
int main(void)
{
int cnt = 0;
for (; scanf("%*s")!=EOF; cnt++)
;
printf("%d", cnt);
return 0;
}
풀이2
- 풀이1에서 백만까지 저장할 수 있는 배열을 선언하는 것이 비효율적이라고 생각했고, 다른 사람들은 도대체 어떻게 풀까 싶어서 검색해보다가 해당 풀이를 발견
- 단 모든 실행환경에서 동작하지는 않는다. 채점환경에서는 제대로 돌아가는데, 내 경우 비쥬얼 스튜디오에서조차 원하는대로 나오지 않음
- ~scanf("%*s")
- scanf("%s")는 whitespace가 아닌 유효 char이 나올 때까지 버퍼를 읽었들이다가 그 다음 공백이 나오면 읽기를 멈춘다.
따라서 문장을 단어(띄어쓰기) 단위로 끊어 읽는 셈이 되기 때문에, 읽기가 종료될 때마다 띄어쓰기 개수를 늘리면 문제를 쉽게 해결할 수 있다.- 또한 첫번째 공백이나 문장 끝의 공백은 무시한다는 점에서 이 문제를 푸는데 해당 접근법이 적합하다.
- 또한 첫번째 공백이나 문장 끝의 공백은 무시한다는 점에서 이 문제를 푸는데 해당 접근법이 적합하다.
- scanf("%*s"): 단어를 읽어와 단어 자체는 소거 (여기서 관심사는 오로지 띄어쓰기의 개수)
- tilde(~)의 역할: binary negation
- stackOverFlow 설명
scanf returns the number of values it scanned successfully or EOF if it reaches the end of file. EOF is a macro that represents a negative value. On most platforms, the value of EOF is (int) -1. In this case, taking 1's complement of -1, will make the value as 0 and is used to break from the loop. - 결국에는 문장이 끝나 scanf의 리턴값이 EOF가 되었을 때 루프를 탈출시키기 위해 negate하는 역할로 '~'가 쓰인다고 한다. 비트연산자인데... 공부를 안해서 솔직히 모르겠다. 대부분의 플랫폼에서 EOF의 값이 -1이기 때문에 비트를 반전시키면서 0으로 만들어 루프를 탈출한단 소리인데, 그렇다면 그냥 EOF일 때로 좀 더 명시적으로 적지 않으면 될까 싶어 코드를 살짝 수정했다. 코드를 단순화하기는 하는데, 좋은 코드인지는 모르겠다
- stackOverFlow 설명
- scanf("%s")는 whitespace가 아닌 유효 char이 나올 때까지 버퍼를 읽었들이다가 그 다음 공백이 나오면 읽기를 멈춘다.
'문제풀이' 카테고리의 다른 글
[C언어] 백준 5622 다이얼 (0) | 2021.12.22 |
---|---|
[C언어] 백준 2908 상수 (0) | 2021.12.22 |
[C언어] 백준 1157 단어공부 (0) | 2021.12.22 |
[C언어] 백준 2675 문자열반복 (0) | 2021.12.21 |
[C언어] 백준 10809 알파벳찾기 (0) | 2021.12.21 |