STEP 3.3B 組み込み関数を使った例

<問題> テキスト中のパターン照合問題について、(簡略) ボイヤームーア法をプログラムせよ。


<実行結果> 

文字列を入力してください :ABABCDEFGHA
探したい文字列を入力してください :ABC ← (ここまで、入力)
s1[0] = A
s1[1] = B
s1[2] = A
s1[3] = B
s1[4] = C
s1[5] = D
s1[6] = E
s1[7] = F
s1[8] = G
s1[9] = H
s1[10] = A
2からマッチしました。


文字列を入力してください :ABABCDEFGHA
探したい文字列を入力してください :TS
s1[0] = A
s1[1] = B
s1[2] = A
s1[3] = B
s1[4] = C
s1[5] = D
s1[6] = E
s1[7] = F
s1[8] = G
s1[9] = H
s1[10] = A
11まで調べましたが、マッチしませんでした

文字列を入力してください :dfefgmiyazakidas
探したい文字列を入力してください :miya
s1[0] = d
s1[1] = f
s1[2] = e
s1[3] = f
s1[4] = g
s1[5] = m
s1[6] = i
s1[7] = y
s1[8] = a
s1[9] = z
s1[10] = a
s1[11] = k
s1[12] = i
s1[13] = d
s1[14] = a
s1[15] = s
5からマッチしました

<ヒント>

例題集へ



解答例

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

int main (void) {
    char s1[30];
    char s2[10];
    int skip[255]; /* 添え字は1バイト文字アスキーに対応  */
    int i; /* テキスト文字列のカウンター */

    int l; /* ループ回数 */
    int m; /* テキストの長さ */
    int n; /* パターンの長さ */

    printf("文字列を入力してください :");
    scanf("%s", s1);
    printf("探したい文字列を入力してください :");
    scanf("%s", s2);

    /* 定番の出力プログラム */
    i = 0;
    while (s1[i] != '\0') {
        printf("s1[%d] = %c\n", i, s1[i]);
        i++;
    }

    m = strlen(s1);
    n = strlen(s2);
    l = m - n;

    /* キーの文字に応じて、何文字ジャンプするか、skipテーブルを作る */
    for (i=0; i < 255; i++)
        skip[i]= n; /* まず全部を、パターンの長さ分ジャンプに設定 */
    for (i=0; i < n - 1 ; i++)
        skip[s2[i]]= n - i - 1;  /* 何文字分ずらしてよいか */

    /* デバッグ用 出力 アルファベットだけ出力*/
    for (i=65; i < 123 ; i++)
        printf("%c= %d\n",i,skip[i]);  /* 何文字分ずらしてよいか */

    i = 0;
    while (i <= l) {
        if (strncmp(&s1[i], s2, n) == 0) {
            break;
        } else {
            i = i + skip[s1[i+n-1]];
        }
    }

    if (i <= l) {
        printf("%dからマッチしました。\n", i);
    } else {
        printf("%dまで調べましたが、マッチしませんでした。\n", l);
    }

    return 0;


}