정답률이 30%대 이하는 아니지만, 특이한 케이스로 헤맨 문제여서 올렸다.
방식은 우선 크로아티아 알파벳을 문자열 내에서 다 찾아내 지워준다. 단, 지운다음에 다음 순회에서 지우고 합쳐진 문자열에서 크로아티아 알파벳으로 오인될 수 있는 경우가 있기 때문에 중간에 0을 넣어준다.
ex 1) nljj 에서 lj를 찾고 알파벳 개수를 증가 시킨 뒤, lj를 지우면 nj가 된다. 문자열 nj가 크로아티아 알파벳으로 오인되어 2개로 카운트하게 된다.
ex 2) nljj 에서 lj를 찾고 알파벳 개수를 증가 시킨 뒤, lj를 지운다. strstr을 이용해 찾아낸 lj가 처음 나타난 인덱스에 '0'을 집어넣고, 그 다음인덱스부터 붙여 넣는다. 그럼 문자열은 n0j가 되고, 알파벳을 잘못 셀 경우가 사라진다.
그 다음 남은 문자열을 하나씩 증가시킨다. 중간에 넣은 0은 세면 안되니까 알파벳이 나타났을 때만 센다.
크로아티아 알파벳의 종류(문자 여러개로 나타내는 경우)는 다음과 같다.
처음에 썼던 정답코드
#include <stdio.h> #include <string.h> int main() { char k_word[8][5] = { "c=\0", "c-\0", "dz=\0", "d-\0", "lj\0", "nj\0", "s=\0", "z=\0" }; char str[101]; char *p; int k_count = 0; int i = 0; scanf("%s", str); for (i = 0; i < 8; i++) { p = str; while (*p) { if (strstr(p, k_word[i])) { k_count++; p = strstr(p, k_word[i]); *p = '0'; *(p + 1) = '\0'; strcat(p, p + strlen(k_word[i])); } else { p++; } } } for (i = 0; str[i]; i++) { if ('a' <= str[i] && str[i] <= 'z') { k_count++; } } printf("%d", k_count); return 0; }
이 문제를 5번 가량 틀렸는데, VS에서는 모든 데이터케이스에서 잘 작동했기 때문에 혼자 골머리 앓다가 질문게시판에 올렸는데, 한 분이 strcat에서의 인자 사용이 매우 위험하다고 하셨다. strcat의 구조를 잘 몰라서 저지른 실수다. (사실 VS에서 메모리 에러는 내지 않았기도 했고) 첫 번째 인자 dest와 두 번째 인자 src를 같은 포인터 변수를 이용해 참조하면 공간 충돌이 일어날 수도 있다고 한다. 위 코드에서는 모두 p를 이용해 넘겨줬다.
진짜 정답코드
#include <stdio.h> #include <string.h> int main() { char k_word[8][5] = { "c=\0", "c-\0", "dz=\0", "d-\0", "lj\0", "nj\0", "s=\0", "z=\0" }; char str[101]; char tmp[101]; char *p; int k_count = 0; int i = 0; scanf("%s", str); for (i = 0; i < 8; i++) { p = str; while (*p) { if (strstr(p, k_word[i])) { k_count++; p = strstr(p, k_word[i]); *p = '0'; *(p + 1) = '\0'; strcpy(tmp, p + strlen(k_word[i])); strcat(p, tmp); } else { p++; } } } for (i = 0; str[i]; i++) { if ('a' <= str[i] && str[i] <= 'z') { k_count++; } } printf("%d", k_count); return 0; }
그래서 tmp를 이용해 주소를 복사 한 뒤, 메모리 충돌을 제거했다. 그렇게 맞았습니다!!를 받아냈다.
제게 도움주신 능력자님, 감사합니다..!
'BOJ' 카테고리의 다른 글
[C] 백준 2839번 설탕 배달 (0) | 2018.07.08 |
---|---|
[C++] 백준 1929번 소수 구하기 (에라토스테네스의 채) (0) | 2018.07.04 |
[C] 백준 1157번 단어 공부 (0) | 2018.07.03 |