【数据结构】第4章 串、数组和广义表 串和KMP算法

【串的顺序存储结构、堆式顺序存储结构、链式存储结构、模式匹配(BF算法和KMP算法)】


串是内容受限的线性表
嘿嘿嘿在B站找着俩视频:
动画理解手算做题

#include<bits/stdc++.h>
using namespace std;
typedef int Status;
typedef int ElemType;
#define OVERFLOW -1
#define ERROR 0
#define OK 1

//------串的顺序存储结构-----
#define MAXLEN 225
typedef struct 
{
    char ch[MAXLEN + 1];    //存储串的一维数组,从下标为1的数组分量开始存储的,下标为0的分量闲置不用 
    int length;             //串的当前长度
}SString;

//------串的堆式顺序存储结构-----
typedef struct 
{
    char *ch;       //若是非空串,则按串长分配存储区,否则ch为NULL
    int length;     //串的当前长度
}HString;

HString S, T;

//-----串的链式存储结构-----
#define CHUNKSIZE 80
typedef struct Chunk
{
    char ch[CHUNKSIZE];
    struct Chunk *next;
}Chunk;
typedef struct
{
    Chunk *head, *tail;     //串的头指针和尾指针
    int length;             //串的当前长度
}LString;

// //1、生成串
// StrAssign(&T, chars)

// //2、复制
// StrCopy(&T, S)

// //3、判空
// StrEmpty(S)

// //4、比较
// StrCompare(S, T)

// //5、长度
// StrLength(S)

// //6、清空
// ClearString(&S)

// //7、联接
// Concat(&T, S1, S2)

// //8、子串
// SubString(&Sub, S, pos, len)

//9、串的模式匹配_BF算法 O(n * m)
int Index_BF(HString S, HString T, int pos)
{//返回模式T在主串s中第pos个字符开始第一次出现的位置。若不存在,则返回值为0
 //其中,T非空,1<=pos<=S.length
    int i = pos, j = 1;                     //初始化
    while(i <= S.length && j <= T.length)   //两串均未比较到串尾
    {
        if(S.ch[i] == T.ch[j])              //继续比较后继字符
        {
            i++;
            j++;
        }
        else                                //指针后退重新开始匹配
        {
            i = i - j + 2;                  //i=i-j+1回到i的起点,+2到下一个字符
            j = 1;
        }
    }
    if(j > T.length)
            return i - T.length;            //匹配成功,返回T在S中第一次出现的位置
        else
            return 0;
}

//9、串的模式匹配_KMP算法求next数组
void get_next(HString, int next[])
{//求模式串T的next函数值并存入数组next
    int j = 1, t = 0;
    next[1] = 0;
    while(j < T.length)
    {
        if(t == 0 || T.ch[j] == T.ch[t])
        {
            t++;
            j++;
            next[j] = t;
        }
        else
            t = next[t];
    }
}

//9、串的模式匹配_KMP算法求nextval数组
void get_nextval(HString T, int nextval[])
{//求模式串T的next函数修正值并存入数组nextval
    int j = 1, t = 0;
    nextval[1] = 0;
    while(j < T.length)
    {
        if(t == 0 || T.ch[j] == T.ch[t])
        {
            t++;
            j++;
            if(T.ch[j] != T.ch[t])
                nextval[j] = t;
            else
                nextval[j] = nextval[t];
        }
        else
            t = nextval[t];
    }
}

//9、串的模式匹配_KMP算法 O(n + m)
int Index_KMP(HString S, HString T, int pos, int next[])
{//利用模式串T的next函数求T在主串S中第pos个字符之后的位置
 //其中,T非空,1<=pos<=S.length 
    int i = pos, j = 1;
    while(i <= S.length && j <= S.length)   //两个串均未比较到串尾
    {
        if(j == 0 || S.ch[i] == T.ch[i])    //继续比较后继字符
        {
            i++;
            j++;
        }
        else
            j = next[j];                    //模式串向右移动
        if(j > T.length)                    //匹配成功
            return i - T.length;
        else
            return 0;
    }
}

// //10、插入
// Strlnsert(&S, pos, T) 

// //11、删除
// StrDelete(&S, pos, len)

// //12、销毁
// DestroyString(&S)


(1)串是一种特殊的线性表,其特殊性体现在( )。
A.可以顺序存储 B.数据元素是一个字符 C.可以链式存储 D.数据元素可以是多个字符若
答案:B

(2)串下面关于串的的叙述中,( )是不正确的?
A.串是字符的有限序列 B.空串是由空格构成的串 C.模式匹配是串的一种重要运算 D.串既可以采用顺序存储,也可以采用链式存储
答案:B
解释:空格常常是串的字符集合中的一个元素,有一个或多个空格组成的串成为空格串, 零个字符的串成为空串,其长度为零。

(3)串“ ababaaababaa ”的 next 数组为( ) 。
A.012345678999 B.012121111212 C.011234223456 D.0123012322345
答案:C

(4)串“ ababaabab”的 nextval为( )。 A.010104101 B.010102101 C.010100011 D.010101011
答案:A

(5)串的长度是指( )。
A.串中所含不同字母的个数 B.串中所含字符的个数 C.串中所含不同字符的个数 D.串中所含非空格字符的个数
答案:B
解释:串中字符的数目称为串的长度

(1)已知模式串t=‘ abcaabbabcab’ 写出用 KMP法求得的每个字符对应的next 和 nextval 函数值。
答案: 在这里插入图片描述

(2)设目标为 t=“ abcaabbabcabaacbacba” , 模式为p=“ abcabaa”
① 计算模式 p 的 naxtval 函数值;
② 不写出算法, 只画出利用 KMP算法进行模式匹配时每一趟的匹配过程。
答案:
① p 的 nextval 函数值为0110132。(p 的 next 函数值为 0111232)
② 利用 KMP( 改进的 nextval) 算法,每趟匹配过程如下:
在这里插入图片描述

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_碗碗儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值