美文网首页
c语言实现BM算法

c语言实现BM算法

作者: 一路向后 | 来源:发表于2021-04-08 22:11 被阅读0次

1.源码实现

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

#define KEYSIZE 256

/*求坏字符偏移*/
void PreBmBc(char *x, int m, int *bc)
{
    int i;

    for(i=0; i<KEYSIZE; i++)
    {
        bc[i] = -1;
    }

    for(i=0; i<m; i++)
    {
        bc[x[i]] = i;
    }

    /*for(i=0; i<m; i++)
    {
        printf("bc[%c]=%d\n", x[i], bc[x[i]]);
    }*/
}

/*求好后缀偏移*/
int PreBmGs(char *pat, int n, int *sf, int *sfl)
{
    int m = n / 2;
    int u = 0;
    int i;
    int j;
    int k = 0;

    for(i=0; i<n; i++)
    {
        sf[i] = -1;
        sfl[i] = 0;
    }

    for(i=0; i<m; i++)
    {
        for(j=0; j<n-1-i; j++)
        {
            u = 1;

            for(k=0; k<=i; k++)
            {
                if(pat[j+k] != pat[n-1-i+k])
                {
                    u = 0;
                    break;
                }
            }

            if(u)
            {
                sf[n-1-i] = j;
                sfl[n-1-i] = i+1;
            }
        }
    }

    for(i=n-2; i>=0; i--)
    {
        if(sf[i+1] < i && sfl[i] < sfl[i+1])
        {
            sf[i] = sf[i+1];
            sfl[i] = sfl[i+1];
        }
    }

    for(i=0; i<n; i++)
    {
        if(sf[i] == -1)
        {
            sf[i] = n - 1;
        }
        else
        {
            /*printf("sf=%d\n", sf[i]);*/
            sf[i] = n - sfl[i] - sf[i];
        }
    }

    /*for(i=0; i<n; i++)
    {
        printf("sf[%d]=%d, sfl[%d]=%d\n", i, sf[i], i, sfl[i]);
    }*/

    return 0;
}

int BM(char *str, int n, char *pat, int m, int *bc, int *sf)
{
    int c, d;
    int i = 0;
    int j = m-1;
    int k = 0;
    int l = 0;

    /*printf("str=%s\n", str);
    printf("pat=%s\n", pat);

    printf("i=%d, j=%d\n", i, j);*/

    while(i+j < n)
    {
        /*printf("str[%d+%d]=%c, pat[%d]=%c\n", i, j, str[i+j], j, pat[j]);*/

        if(str[i+j] != pat[j])
        {
            c = j - bc[str[i+j]];
            d = 0;

            if(j+1 < m)
            {
                /*printf("sf[%d]=%d\n", j+1, sf[j+1]);*/
                d = sf[j+1];
            }

            /*printf("c=%d, d=%d\n", c, d);*/

            /*偏移值为坏字符和好后缀的最大值*/
            i += (c > d ? c : d);

            j = m - 1;

            l++;
        }
        else
        {
            j--;
        }

        if(j == -1)
        {
            /*printf("%d\n", i);*/
            break;
        }
    }

    if(j != -1)
    {
        return -1;
    }

    return i;
}

int main()
{
    FILE *fp;
    char str[4096] = "abcacabbcabccabc";
    char pat[1024] = "your";
    int bc[256];
    int sf[256];
    int sfl[256];

    int n = strlen(str);
    int m = strlen(pat);
    int u;
    int k = 0;

    PreBmBc(pat, m, bc);
    PreBmGs(pat, m, sf, sfl);

    /*u = BM(str, n, pat, m, bc, sf);

    printf("u=%d\n", u);*/

    fp = fopen("1.txt", "r");

    memset(str, 0x00, sizeof(str));

    while(fgets(str, 2048, fp) != NULL)
    {
        n = strlen(str);

        k++;

        /*printf("BM begin %d\n", k);*/

        u = BM(str, n, pat, m, bc, sf);

        /*printf("BM end\n");*/

        if(u >= 0)
        {
            printf("%d\n", u);
        }

        memset(str, 0x00, sizeof(str));
    }

    fclose(fp);

    return 0;
}

2.编译源码

$ gcc -o example examle.c -std=c89

4.运行及其结果

$ ./example
839
378
744

相关文章

网友评论

      本文标题:c语言实现BM算法

      本文链接:https://www.haomeiwen.com/subject/mlkbkltx.html