数据结构05:串

1. 串的定义

串是由零个或多个字符组成的有限序列,又名字符串。

2. 串的比较

给定两个串: s=a1a2an s = a 1 a 2 ⋯ a n , t=b1b2bm t = b 1 b 2 ⋯ b m ,当满足以下条件之一时,s < t
1. n < m,且 ai=bi a i = b i (i = 1, 2, ……, n)
例如当s=“hap”,t=”happy”,就有s < t。因为t比s多出了两个字母
2. 存在某个k<=min(m,n),使得 ai=bi a i = b i (i = 1, 2, ……, k-1), ak<bk a k < b k
例如当s=”happen”,t=”happy”,因为两串的前4个字母均相同,而两串第5个字母(k值),字母e的ASCII码是101,而字母y的ASCII码是121,显然e < y,所以s < t

3. 串的抽象数据类型

ADT 串(string)
Data
    串中元素仅由一个字符组成,相邻元素具有前驱和后继关系。
Operation
    StrAssign(T, *chars):生成一个其值等于字符串常量chars的串T
    StrCopy(T, S):串S存在,由串S复制得串T
    ClearString(S):串S存在,将串清空
    StringEmpty(S):若串S为空,返回true,否则返回false
    StrLength(S):返回串S的元素个数,即串的长度
    StrCompare(S, T):若S > T,返回值 > 0,若S = T,返回0,若S < T,返回值 < 0
    Concat(T, S1, S2):用T返回由S1和S2连接而成的新串
    SubString(Sub, S, pos, len):串S存在,1 <= pos <= StrLength(S),
        且0 <= len <= StrLength(S) - pos + 1,用Sub返回串S的第pos个字符起长度为len的子串
    Index(S, T, pos):串S和T存在,T是非空串,1 <= pos <= StrLength(S)。若主串S中存在和串T值相同的子串,
        则返回它在主串S中第pos个字符之后第一次出现的位置,否则返回0。
    Replace(S, T, V):串S,T和V存在,T是非空串。用V替换主串S中出现的所有与T相等的不重叠子串。
    StrInsert(S, pos, T):串S和T存在,1 <= pos <= StrLength(S) + 1。在串S的第pos个字符串之前插入串T
    StrDelete(S, pos, len):串S存在,1 <= pos <= StrLength(S) - len + 1。
        从串S中删除第pos个字符起长度为len的子串
endADT

4. 串的存储结构

4.1 串的顺序存储结构

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

4.2 串的链式存储结构

对于串的链式存储结构,与线型表是相似的,一个结点可以存放一个或多个字符,最后一个结点若未被占满,可以用其他字符补全。

5. 朴素的模式匹配算法

字符串的定位操作通常称做串的模式匹配
朴素模式匹配,即通过挨个遍历的方法进行比对,效率相对底下。

/* 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数返回值为0*/
/* T非空,1 <= pos <= StrLength(S) */
int Index(String s, String T, int pos) {
    int i = pos;
    int j = 1;
    while(i <= S[0] && j <= T[0]) {
        if(S[i] == T[j]) {
            ++i;
            ++j;
        } else {
            i = i - j + 2;
            j = 1;
        }
        if(j > T[0])
            return i - T[0];
        else
            return 0;
    }
}

6. KMP模式匹配算法

6.1 KMP模式匹配算法原理

数据结构05:串_第1张图片
我们可以根据经验得到如果前后缀一个字符相等,k值是2,两个字符k值是3,n个相等k值就是n + 1。

6.2 next数组值推导

  1. T = “abcdex”
    这里写图片描述
  2. T = “abcabx”
    这里写图片描述
  3. T = “ababaaaba”
    这里写图片描述
  4. T = “aaaaaaaab”
    这里写图片描述

6.3 KMP模式匹配算法实现

/* 通过计算返回子串Tnext数组 */
void get_next(String T, int *next) {
    int i, j;
    i = 1;
    j = 0;
    next[1] = 0;
    while(i < T[0]) {    /* 此处T[0]表示串T的长度 */
        if(j == 0 || T[i] == T[j]) { /* T[i]表示后缀的单个字符,T[j]表示前缀的单个字符 */
            ++i;
            ++j;
            next[i] = j;
        } else 
            j = next[j];
    }
}
/* 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数返回值为0 */
/* T非空,1 <= pos <= StrLength(S) */
int Index_KMP(String S, String T, int pos) {
    int i = pos;
    int j = 1;
    int next[255];
    get_next(T, next);
    while(i <= S[0] && j <= T[0]) {
        if(j == 0 || S[i] == T[j]) { /* 两字母相等则继续 */
            ++i;
            ++j;
        } else {
            j = next[j];
        }
    }
    if(j > t[0])
        return i - T[0];
    else
        return 0;
}

6.4 KMP模式匹配算法改进

/* 求模式串Tnext函数修正值并存入数组nextval */
void get_nextval(String T, int *nextval) {
    int i, j;
    i = 1;
    j = 0;
    nextval[1] = 0;
    while(i < T[0]) {
        if(j == 0 || T[i] == T[j]) {
            ++i;
            ++j;
            if(T[i] != T[j])
                nextval[i] = j;
            else
                nextval[i] = nextval[j];
        } else
            j = nextval[j];
    }
}

实际匹配算法,只需要将”get_next(T, next;”改为”get_nextval(T, next)”

6.5 nextval数组值推导

  1. T=”ababaaaba”
    数据结构05:串_第2张图片
  2. T=”aaaaaaaab”
    数据结构05:串_第3张图片

你可能感兴趣的:(数据结构)