白駿2941号


BOJ 2941:クロアチア文字
問題そのものにも考える余地があり、実施する際にも注意点があります
アルファベットを1文字読んでからカウントダウンするのが原則ですが、クロアチア文字は、1回に2文字か3文字読むときにも発生します.
ここでは、1つのカウンタから、読み取った個数だけで2個、3個になって手に入れることができます
重複するfor文では、インデックスiとi+1でクロアチア文字とstr値を比較し、クロアチア文字と同じであればi++でi値を1増加することは、2つの読み取りに等しい.
重複するfor文を離れてcount++でcount値を1つ追加すると、アルファベット数を1つ使用することになります.
このときクロアチア文字の「dz=」は3文字で問題になります.
「dz=」以外は、どのアルファベットやクロアチアアルファベットの後ろにも「=」が単独で表示されないため、クロアチアアルファベットの上位2桁が同じ状態で、次のアルファベットに「=」が表示された場合は「dz=」で確認します.
この確認過程は正しいが、問題はクロアチア文字ではない部分にある.
「dzz」のように3文字で読み出す必要がある場合でも、前の2文字は「dz=」の「d」、「z」と同じであることがわかり、ifゲートを離れるとi++で処理される.従って、else ifがj=2であることを確認し、現在の読み出しが「dz」である場合、後に'='がない場合、breakを設定してi++の処理を回避する.もちろん,最も埋め込まれたif-if else文と次のi++との順序も重要である.

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

int main()
{
    const char* croatian[] = { "c=" , "c-" , "dz=", "d-", "lj", "nj", "s=", "z=" };

    char str[101] = "";

    while (scanf("%s", &str) != 1) continue;
    
    char str_len = strlen(str);

    char count = 0;

    for (int i = 0; i < str_len; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            if ( (str[i] == croatian[j][0]) && (str[i + 1] == croatian[j][1]) )
            {
                if (str[i + 2] == '=')
                    i++;
                else if (j == 2)
                    break;
                i++;
                break;
            }
        }
        count++;
    }

    printf("%d", count);
}