My Gitee Link

数据结构笔记 — 串


 

1.1 串概念
  • (String) 是由零个或者多个字符组成的有限序列,又名字符串

  • 字符串的存储结构与线性表相同,也分顺序存储结构和链式存储结构

  • 字符串的顺序存储结构是用一组地址连续的存储单元来存储串中的字符序列的

  • 不同的是字符串我们一般都是连在一起表述的,“断章取义”的情况并不多,所以习惯上我们通常还是会直接定义一个足够长度的存储区来存储

1.2 BF 算法
  • BF 算法属于朴素的模式匹配算法

  • 有两个字符串 ST ,长度为 NM 。首先 S[1]T[1] 比较,若相等,则再比较 S[2]T[2] ,一直到 T[M] 为止;若 S[1]T[1] 不等,则 T 向右移动一个字符的位置,再依次进行比较

  • 在这里 S 是主串,T 是子串,这种子串的定位操作通常称作 串的模式匹配

    #include <stdio.h>
    #include <string.h>
    ​
    ​
    int BF(char *father, char *son){
        int i = 0, j = 0;
        while (i < strlen(father) && j < strlen(son)){
            if (father[i] == son[j]){
                i++;
                j++;
            } else{
                i = i - j + 1;
                j = 0;
            }
        }
        if (j == strlen(son)){
            return i - strlen(son) + 1;
        }
        return 0;
    }
    ​
    int main(){
        char *father = "SKG0531JJY0618";
        char *son = "531JJY";
        int relust = BF(father, son);
        printf("子串在主串中所在位置为第 %d 位!\n", relust);
        return 0;
    }
1.3 KMP 算法
/**
 * KMP 算法
 * 算法的核心 : next 数组元素的确定
 * 该算法与目标串(S)无关,只与匹配串(T)的失配位置的前后缀数量有关
 *  T    9   a   b   a   b   a   a   a   b   a
 * 下标   0   1   2   3   4   5   6   7   8   9
 * next  -   0   1   1   2   3   4   2   2   3
 */
​
#include <stdio.h>
#include <string.h>
typedef char* String;

//获得 KMP 算法的 next 数组
void getNext(String T, int *next){
    int j = 0;
    int i = 1;
    next[1] = 0;

    while (i < strlen(T)){
        if (j == 0 || T[i-1] == T[j-1]){
            i++;
            j++;
            if (T[i-1] != T[j-1]){
                next[i] = j;
            } else{
                next[i] = next[j];
            }
        } else{
            j = next[j];
        }
    }
}

//返回子串 T 在主串 S 第 pos 个字符之后的位置,不存在返回 0
int IndexKMP(String S, String T){
    int i = 1;
    int j = 1;
    int next[255];

    getNext(T, next);

    while (i <= strlen(S) && j <= strlen(T) ){
        if (j == 0 || S[i-1] == T[j-1]){
            i++;
            j++;
        } else{
            j = next[j];
        }
    }
    if (j > strlen(T)){  //匹配成功,返回位置
        return i - (int)strlen(T);
    } else{
        return -1;
    }
}

int main(){

    String S = "SKG0531JJY0618";
    String T = "JY061";
    int pos = IndexKMP(S, T);
    printf("子串 %s 在父串 %s 中第 %d 个位置!\n", T, S, pos);

    return 0;
}

 

>>>>> END <<<<<

 

posted @ 2020-12-18 16:23  笨草戆沐  阅读(297)  评论(0)    收藏  举报