프로그래밍/백준

[백준 C언어] 2941. 크로아티아 알파벳

서요서요 2022. 12. 29. 20:19

문제

예전에는 운영체제에서 크로아티아 알파벳을 입력할 수가 없었다. 따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다.

예를 들어, ljes=njak은 크로아티아 알파벳 6개(lj, e, š, nj, a, k)로 이루어져 있다. 단어가 주어졌을 때, 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.

dž는 무조건 하나의 알파벳으로 쓰이고, d와 ž가 분리된 것으로 보지 않는다. lj와 nj도 마찬가지이다. 위 목록에 없는 알파벳은 한 글자씩 센다.

입력

첫째 줄에 최대 100글자의 단어가 주어진다. 알파벳 소문자와 '-', '='로만 이루어져 있다.

단어는 크로아티아 알파벳으로 이루어져 있다. 문제 설명의 표에 나와있는 알파벳은 변경된 형태로 입력된다.

출력

입력으로 주어진 단어가 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.

 

 

나의 풀이

#include <stdio.h>
#include <string.h>

char cAlpha[8][4] = { "c=","c-","dz=","d-","lj","nj","s=","z=" }; //lookup array

int main(void) {

    int flag=0, cnt=0; //flag : 크로아티아 알파벳 여부, cnt : 알파벳 개수
    char input[101] = "";
    scanf("%s", input);
    char* p = input; //배열 포인터

    while (*p) {  //p가 가리키는 메모리가 null이 아닐 때까지 반복(문자열의 끝까지 반복)
        for (int j = 0; j < 8; j++) { //lookup array 전체 비교
            if (!strncmp(p, cAlpha[j], strlen(cAlpha[j]))) { //크로아티아 알파벳일 경우
                cnt++;	//크로아티아 알파벳일 경우 단어 카운트++
                flag = 1; 
                p += strlen(cAlpha[j]); //포인터를 크로아티아 알파벳의 길이만큼 이동
                break;
            }
        }
        if (!flag) { //크로아티아 알파벳이 아니었을 경우
            cnt += 1; //단어 카운트 ++
            p += 1;  // 포인터 1만큼 이동
        }
        flag = 0; //플래그 초기화
    }

    printf("%d", cnt);

    return 0;

}

크로아티아 알파벳의 배열을 따로 선언해준 뒤, 

문자열 포인터를 활용하여 문자열의 처음부터 끝까지 배열 요소와의 일치 여부를 조사해주었다.

로직은 다음과 같다. 

 

(0. 문자열 입력받은 후 포인터 선언)

1. 문자열 시작 부분(포인터)에 크로아티아 알파벳이 있는지 확인

2. 크로아티아 알파벳이 맞을 경우 카운트변수 +1, 플래그변수=1, 포인터 알파벳의 길이만큼 이동

3. 크로아티아 알파벳이 아닐 경우 카운트변수 +1, 포인터 1만큼 이동

4. 플래그변수 1로 바꿔준 후 포인터가 NULL을 가리키지 않을 때까지 반복

 

strncmp는 strcmp와 비슷한 기능을 하지만, 매개변수로 비교할 문자열의 크기를 추가로 받는다. 

if (!strncmp(p, cAlpha[j], strlen(cAlpha[j])))

p(문자열 포인터)와  cAlpha[j](크로아티아 알파벳)을 cAlpha[j]의 길이만큼 비교했을 때 

양 문자열이 같으면 if문 안의 코드가 실행된다.

 

이 방식 외에도, 그냥 if문 조건을 input[i]=="c"&&input[i+1]=="=" ...로 주어서 

배열 끝까지 쭉 조사하는 방법이 있다. 

 

* 비교를 할 일이 있을 때는 항상 lookup array를 선호하는 편이다. 

  유지보수가 훨씬 더 용이하기 때문이다...

  이렇게 짤 경우 비교기준이 바뀔 경우 lookup array만 수정해주면 된다. 

  물론 아주 간단한 코테같이 조그만 프로그램이라면 고려대상에서 후순위로 미뤄놔도 되겠지만.