数据结构(四)串

2021-08-22  本文已影响0人  AdRainty

4.1 串的定义

字符串简称串,是一种由零个或多个字符多个字符组成的有限序列


串.png

S = "a_1a_2\cdots a_n" (n \ge 0)

1、字串的任意个,即n可以为0
2、字符串的位序从1开始而不是从0开始
3、空格也算一个字符

4.2 串的基本操作

StrAssign(&T, chars) 赋值,把串T赋值为chars
StrCopy(&T,S) 复制,由串S复制得串T
StrEmpty(S) 判空
StrLength(S) 求串长,即S的元素个数
ClearString(&S) 清空,将S清为空串
DestotyString(&S) 销毁串,将S销毁,回收存储空间
Concat(&T, s1, s2) 串连接,用T返回s1和s2连接的字符串
SubString(&Sub, S, pos, len)求字串,用Sub返回串S第pos个字符起长度为len的字串
Index(S,T)定位,若S中存在T相同字串,返回第一次出现的位置,否则返回0
StrCompare(S,T), 比较,若S>T返回>0,若S<T,返回<0

4.3 串的存储结构

4.3.1 顺序存储

4.3.1.1 初始化

typedef struct {
    char ch[MaxSize];
    int length;// 串实际长度
}SString;

4.3.1.2 求字串

bool SubString(SString S, SString * sub, int pos, int len)
{
    // 首先判断子串是否包含在当前字符串内
    if (pos + len  -1 > S.length) return false;
    for (int i = pos; i < pos+len; i++)
    {
        sub.ch[sub.pos+1] = S.ch[i];
    }
    sub.length = len;
    return true;
}

4.3.1.3 比较

int StrCompare(SString S, SString T)
{
    for (int i = 1; i<=S.length && i <=T.length; i++) 
            if (S.ch[i] != T.ch[i]) return (S.ch[i] - T.ch[i])
    return S.length - T.length;
}

4.3.1.4 定位

int Index(SString S, SString T)
{
    int i = 1; n = StrLength(S), m =StrLength(T)
    SString sub;
    while (i < n-m+1)
    {
        SubString(S, &sub, i, m);
        if (StrComp(T, sub) != 0) i++;
        else return i;
    }
    return 0;
}

4.3.2 堆分配存储结构

typedef struct{
        char *ch;
        int length;
} HString;

HString S;
S.ch = (Char *) malloc (Maxlen * sizeof(char));
S.length = 0;

4.3.3 块链存储

typedef struct StringNode{
        char ch[4];
        struct StringNode *next;
}StringNode,  *String;

4.4 串的模式匹配

子串是主串的一部分,一定存在,模式串不一定能在主串中找到

4.4.1 朴素模式匹配算法

int Index(SString S, SString T)
{
    // 定义两个指针分别指向主串和模式串,主要通过改变两个指针而不需要去进行串操作
    int i = 1,j = 1;
    while (i < S.length && j < T.length) {
        if (S.ch[i] == T.ch[j]) {
            i++;
            j++;
        }
        else {
            i = i - j + 2;
            j = 1;
        }
    }
    if (j == T.length) return i - T.length + 1;
    else return 0;
}

最多对比n-m+1次
时间复杂度为O(nm)

4.4.2 KMP算法

void Index_KMP(SString S, SString T, int pos){
    // i 目标串指针,j 模式串指针
    i = pos; j = 1;
    while( i <= length(S) && j <= length(T)){
        // 如果将要和 目标串元素 匹配的元素是模式串首元素前一位的元素
        // 当前目标串元素 和 模式串元素可以匹配
        // if (j == first_indexof(T) - 1 || S[i] == T[j]){
        if(j == 0 || S[i] == T[j]){
            // 指针各自右移一位,这也是为什么j==0时需要放在一起判断的原因
            ++i;
            ++j;
        }else{
            // 发生了失配,查Next数组移动模式串指针
            j = next[j];
        }
    }
    if (j > length(T)){
        // 如果模式串指针溢出了(模式串指针匹配完毕了所有模式串中的元素)
        return i - length(T);
    }
    else return 0;
}

KMP算法主要掌握手算next数组的方法,其中next[1]=0,next[2]=1

上一篇 下一篇

猜你喜欢

热点阅读