백준 웹사이트 "2941번 - 크로아티아 알파벳" 문제풀이입니다.
언어는 C언어입니다. (제출 언어: C99)
문제
소스 코드
#include <stdio.h>
#include <string.h>
int main(void){
char croatia_alphabet[8][4] = {"c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z="};
char input[101];
scanf("%s", input);
int input_len = strlen(input);
int count = 0; // 알파벳의 개수
int cr_count = 0; //크로아티아 알파벳 표현에 쓰인 char 개수
// 1. 입력 문자열 중 croatia_alphabet에 있는 알파벳들 count
for(int num=0; num<8; num++){ // 각각의 croatia alphabet
int alphabet_len;
if(num==2)
alphabet_len = 3; // "dz="일 경우, 길이가 3
else
alphabet_len = 2;
// 2글자(혹은 3글자)씩 croatia_alphabet인지 확인
for(int i=0; i<=input_len-alphabet_len; i++){
int is_croatia = 0; // 0: false, 1: true
for(int j=0; j<alphabet_len; j++){
if(input[i+j] != croatia_alphabet[num][j])
break; // 'break'는 하나의 for문만 탈출
if(j==alphabet_len-1){
is_croatia = 1;
//printf("%s\n", croatia_alphabet[num]);
}
}
if(is_croatia){ // croatia_alphabet이면 실행
if(num==2){ // "dz="일 경우, 3글자이고 "z=" 에서 중복되므로 예외 처리
cr_count+=3; // (+) 3글자
cr_count-=2; // (-) 2글자
}
else{
count++;
cr_count+=2;
}
}
}
}
// 2. 남은 알파벳들 count
count += input_len - cr_count;
printf("%d\n", count);
}
문제 풀이
5622번 문제에서 다이얼을 만들었던 것처럼 참고할 수 있는 크로아티아 알파벳(croatia_alphabet)을 2차원 배열로 만들어줍시다. 2차원 배열에 대한 설명, 그리고 그 크기를 정할 때 주의할 점에 대해서는 5622번 문제 풀이를 확인해주세요!
아래는 백준 웹사이트 "5622번 - 다이얼" 문제풀이 링크입니다.
이제 본격적인 문제 풀이로 들어가봅시다. 먼저 'count'와 'cr_count' 두 가지 변수를 선언 및 초기화하는데, count는 총 알파벳의 개수이며, cr_count는 크로아티아 알파벳 표현을 위해 쓰인 문자의 개수입니다. 예를 들어, 입력 단어가 "ljes=njak"이면 알파벳은 "lj, e, s=, nj, a, k"로 총 6개이므로 count=6이 되어야 하고, 크로아티아 알파벳 표현을 위해 쓰인 문자의 개수는 "l, j, s, =, n, j"로 총 6개이므로 cr_count=6이 되어야 합니다. 문제 풀이가 크게 두 부분으로 나뉘는데, 아래 첫 번째 부분에서는 입력 단어를 분석하여 cr_count의 값을 구하며, 두 번째 부분에서는 cr_count를 이용해 총 알파벳의 개수를 구합니다.
1. 입력 문자열 중 크로아티아 알파벳에 있는 알파벳들을 세어줍니다.
전체 흐름은 8개의 크로아티아 알파벳 각각에 대해, 알파벳의 길이를 구하고 (Line 14~18), 단어에 그 알파벳이 속해있는지를 확인하고 (Line 21~30), 속해있다면 이를 count와 cr_count에 반영해주는 것입니다 (Line 32~41).
Line 14 ~ 18에서는 크로아티아 알파벳의 길이를 구해줍니다. 'alphabet_len'이 알파벳의 길이를 뜻하는 변수이며, "dz="일 경우를 제외하고는 그 값이 항상 2입니다. "dz="일 경우에만 예외적으로 길이가 3이기에, 'alphabet_len = 3'가 되도록 합니다.
Line 21 ~ 30은 입력된 단어에 해당 크로아티아 알파벳이 속해있는지를 확인하는 단계입니다. 이때 입력 단어를 2글자 (혹은 3글자)씩 확인하여, 해당 알파벳인지 확인합니다. 입력 단어가 "ljes=njak"이라면 lj → je → es → s= → ... 순서로 확인을 합니다. 만약 현재 검사하고 있는 알파벳이 "s="이라면, 4번째 순서에서 확인되겠죠? 이렇게 확인되면, 미리 선언한 'is_croatia' 변수가 0에서 1로 바뀌어, Line 32의 if문이 실행됩니다.
Line 32 ~ 41은 크로아티아 알파벳의 존재를 'count'와 'cr_count'에 반영해주는 단계입니다. 검사하는 알파벳이 "dz="가 아니라면, 알파벳의 개수가 1 늘어나야 하므로 count를 1 증가시키고, 알파벳 표현을 위해 쓰인 문자가 2개이므로 cr_count를 2 증가시킵니다. 예외적으로 검사하는 알파벳이 "dz="일 경우, cr_count를 2가 아니라 3을 증가시켜야겠죠? 또한, "dz="는 나중에 "z="을 검사할 때 반드시 중복으로 검사되기 때문에, 이를 감안하여 count를 증가시키지 않습니다. 'cr_count'를 3만큼 증가시킨 후, 2만큼 다시 감소시키는 이유 역시 이러한 중복 때문입니다.
2. 크로아티아가 아닌 알파벳들을 세어줍니다.
거의 끝났습니다. 입력 단어를 분석하여 count와 cr_count를 구했을텐데, 아직 count에는 크로아티아 알파벳의 개수만 저장되어 있습니다. 이제 크로아티아 알파벳이 아닌, 일반 알파벳도 더해줄 차례입니다. 일반 알파벳은 문자 하나가 곧 그 알파벳이므로, 일반 알파벳의 총 개수는 (전체 문자의 개수) - (크로아티아 알파벳에 쓰인 문자의 개수) 방식으로 구할 수 있습니다. 이때 (크로아티아 알파벳에 쓰인 문자의 개수)가 바로 미리 구해놓은 cr_count입니다! 따라서 이를 적용시키면, 최종적으로 구해지는 count는 저희가 어렵사리 찾아 헤매던 정답입니다.
'코딩 > 백준 BOJ' 카테고리의 다른 글
[백준/C언어] 1712번 - 손익분기점 (0) | 2022.01.14 |
---|---|
[백준/C언어] 1316번 - 그룹 단어 체커 (0) | 2022.01.13 |
[백준/C언어] 5622번 - 다이얼 (0) | 2022.01.12 |
[백준/C언어] 2908번 - 상수 (0) | 2022.01.11 |
[백준/C언어] 1152번 - 단어의 개수 (0) | 2022.01.11 |