字符串匹配 - BF算法

·  阅读 244

题目

有一个主串 S = {a,b,c,a,c,a,b,d,c},模式串 T = {a,b,d};请找到模式串在主串中第一次出现的位置;(提示:并不需要考虑字符串大小写的问题,字符均为小写字母)

BF算法思想

BF算法,即暴力(Brute Force)算法,其核心思想是:将主串和模式串逐个比较,如上图所示,从下标1开始,s[1] = a,T[1] = a,相同就接着往后比较,直到s[3] = c,T[3] = d,说明匹配不成功,需要对主串下标进行回退到下标2,子串回退到下标1,重新新一轮的比较,此时s[2] != T[1],匹配不成功,此时主串下标指向3,子串又回退到下标1,继续比较,直到完全匹配成功。

BF算法实现

#define OK 1
#define ERROR 0
#define MAXSIZE 40    /* 存储空间初始分配量 */
typedef int Status;   /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef char String[MAXSIZE+1]; /*  0号单元存放串的长度 */

/* 生成一个其值等于chars的串T */
Status StrInit(String T,char *chars) {
    if (strlen(chars) > MAXSIZE) {
        return ERROR;
    }
    T[0] = strlen(chars);
    for (int i = 1; i < T[0] + 1; i ++) {
        T[i] = *(chars+i-1);
    }
    return OK;
}

/* 输出串T*/
void StrPrint(String T) {
    for (int i = 1; i < T[0] + 1; i++) {
        printf("%c",T[i]);
    }
    printf("\n");
}

/* BF算法 */
int Index_BF(String S, String T,int pos){
    
    //i用于主串S中当前位置下标值,若pos不为1,则从pos位置开始匹配
    int i = pos;
    //j用于子串T中当前位置下标值
    int j = 1;
    
    //若i小于S的长度并且j小于T的长度时,循环继续
    while (i <= S[0] && j <= T[0]) {
        
        //比较的2个字母相等,则继续比较
        if (S[i] == T[j]) {
            i++;
            j++;
        }else
        {
            //不相等,则指针后退重新匹配
            
            //i 退回到上次匹配的首位的下一位;
            //加1,因为是子串的首位是1开始计算;
            //再加1的元素,从上次匹配的首位的下一位;
            i = i-j+2;
            
            //j 退回到子串T的首位
            j = 1;
        }}
    
    //如果j>T[0],说明T已经遍历结束,表示匹配成功
    if (j > T[0]) {
        //i母串遍历的位置 - 模式字符串长度 = index 位置
        return  i - T[0];
    }else{
        return -1;
    }
    
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        
        String s;
        StrInit(s, "abcacabdc");
        
        String t;
        StrInit(t, "abd");
        
        int index = Index_BF(s, t, 1);
        printf("index = %d\n",index);
        
    }
    return 0;
}

复制代码

BF算法优缺点

优点:暴力,实用,代码简单,易理解

缺点:时间复杂度高,有很多无意义的遍历,例如主串为“0000000000”,子串为“000000001”

分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改