2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】

本文涉及的产品
视觉智能开放平台,视频资源包5000点
视觉智能开放平台,分割抠图1万点
视觉智能开放平台,图像资源包5000点
简介: 数据结构与算法系列学习之串的定义和基本操作、串的储存结构、基本操作的实现、朴素模式匹配算法、KMP算法等代码举例及图解说明;【含常见的报错问题及其对应的解决方法】你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!

欢迎各位彦祖与热巴畅游本人专栏与博客

你的三连是我最大的动力

以下图片仅代表专栏特色 [点击箭头指向的专栏名即可闪现]

专栏跑道一

➡️网络空间安全——全栈前沿技术持续深入学习

image.gif

专栏跑道二

➡️ 24 Network Security -LJS

image.gif

image.gif

image.gif

专栏跑道三


➡️ MYSQL REDIS Advance operation

image.gif

专栏跑道四

➡️HCIP;H3C-SE;CCIP——LJS[华为、华三、思科高级网络]

image.gif

专栏跑道五

➡️RHCE-LJS[Linux高端骚操作实战篇]

image.png

专栏跑道六

➡️数据结构与算法[考研+实际工作应用+C程序设计]

image.gif

专栏跑道七

➡️RHCSA-LJS[Linux初级及进阶骚技能]

image.gif

image.gif

上节回顾



数据结构与算法系列学习之串

1.串的定义和基本操作

1.1定义:

  • 串,即字符串(String)是由零个或多个字符组成的有限序列。一般记为S = ‘a1a2······an' (n ≥0)
  • 其中,S是串名,单引号括起来的字符序列是串的值;ai可以是字母、数字或其他字符;串中字符的个数n称为串的长度。n = 0时的串称为空串(用∅表示)。
  • 有的地方用双引号(如Java、C),有的地方用单引号(如Python)
  • 例如:S=”HelloWorld!”T=‘iPhone 14 Pro Max?’
  • 子串:串中任意个连续的字符组成的子序列。Eg:’iPhone’,’Pro M’是串T的子串
  • 主串:包含子串的串。Eg:T是子串’iPhone’的主串
  • 字符在主串中的位置:字符在串中的序号。Eg:’1’在T中的位置是8(第一次出现)
  • 子串在主串中的位置子串的第一个字符在主串中的位置。Eg:’14Pro’在T中的位置为8
  • 每个空格字符占1B,不是空串
  • 串的位序从1开始而不是从0开始
  • 串是一种特殊的线性表,数据元素之间线性关系
  • 串的数据对象限定为字符集(如中文字符、英文字符、数字字符、标点字符等)
  • 串的基本操作,如增删改查等通常以子串为操作对象,因为人类的语言通常要多个字符组成的序列才有现实意义

1.2串的基本操作

假设有串 T = '', S = 'iPhone 14 Pro Max?', W = 'Pro'

  • StrAssign(&T, chars): 赋值操作,把串T赋值为chars;
  • StrCopy(&T, S): 复制操作,把串S复制得到串T
  • StrEmpty(S): 判空操作,若S为空串,则返回TRUE,否则返回False;
  • StrLength(S): 求串长,返回串S的元素个数;
  • ClearString(&S): 清空操作,将S清为空串;
  • DestroyString(&S): 销毁串,将串S销毁——回收存储空间;
  • Concat(&T, S1, S2): 串联联接,用T返回由S1和S2联接而成的新串———可能会导致存储空间的扩展;
  • 例:
Concat(&T, S, W)
T = ‘iPhone 14 Pro Max?Pro’
  • image.gif
  • SubString(&Sub, S, pos, len): 求子串,用Sub返回串S的第pos个字符起长度为len的子串;
SubString(&T, S, 4, 6)
T = ‘one 14’

image.gif

  • Index(S, T): 定位操作,若主串S中存在与串T值相同的子串,则返回它再主串S中第一次出现的位置,否则函数值为0;
  • StrCompare(S, T): 串的比较操作,参照英文词典排序方式;若S > T,返回值>0; S = T,返回值=0 (需要两个串完全相同) ; S < T,返回值<0;

1.3字符集编码:

  • 任何数据存到计算机中一定是二进制数。
  • 需要确定一个字符和二进制数的对应规则这就是“编码”
  • “字符集”:英文字符,ASCII字符集,中英文,Unicode字符集
  • 基于同一个字符集,可以有多种编码方案,如:UTF-8,UTF-16
  • 注:采用不同的编码方式,每个字符所占空间不同,考研中只需默认每个字符占1B即可

image.gif 编辑

2.串的储存结构

2.1顺序存储:

image.gif

代码实现:

#define MAXLEN 255   //预定义最大串长为255
typedef struct{
    char ch[MAXLEN];   //静态数组实现(定长顺序存储)
                       //每个分量存储一个字符
                       //每个char字符占1B
    int length;        //串的实际长度
}SString;

image.gif

  • 方案一:一个数组来储存字符,一个int变量length储存实际长度
  • 方案二:数组的ch[0]来充当length,优点:字符的位序和数组下标相同
  • 方案三:没有Length变量,以字符’\0’表示结尾(对应ASCII码的0),缺点:获取字符串长度需要遍历,时间复杂度高
  • 方案四:数组的ch[0]废弃不用,从看开始储存字符,外加一个int变量length储存实际长度

2.2链式存储

image.gif

代码实现:

typedef struct StringNode{
    char ch;           //每个结点存1个字符
    struct StringNode *next;
}StringNode, * String;
问题:存储密度低,每个字符1B,每个指针4B;
解决方案:每一个链表的结点存储多个字符——每个结点称为块——块链结构
typedef struct StringNode{
    char ch[4];           //每个结点存多个个字符
    struct StringNode *next;
}StringNode, * String;
image.gif
  • 推荐使用第二种方式,存储密度较高,ch数组未必一定是4个字符,也可以比4多

3.基本操作的实现(使用第四种方案):

image.gif 编辑

image.gif 编辑

image.gif 编辑

基本操作代码实现[方案4]:

#define MAXLEN 255
typedef struct{
    char ch[MAXLEN];   
    int length;       
}SString;
// 1. 求子串
bool SubString(SString &Sub, SString S, int pos, int len){
    //子串范围越界
    if (pos+len-1 > S.length)
        return false;
    
    for (int i=pos; i<pos+len; i++)
        Sub.cn[i-pos+1] = S.ch[i];
    
    Sub.length = len;
    return true;
}
// 2. 比较两个串的大小
int StrCompare(SString S, SString T){
    for (int i; 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;
}
// 3. 定位操作
int Index(SString S, SString T){
    int i=1;
    n = StrLength(S);
    m = StrLength(T);
    SString sub;        //用于暂存子串
    while(i<=n-m+1){
        SubString(Sub,S,i,m);
        if(StrCompare(Sub,T)!=0)
            ++i;
        else 
            return i;    // 返回子串在主串中的位置
    }
    return 0;            //S中不存在与T相等的子串
}
image.gif

4.朴素模式匹配算法

4.1字符串模式匹配:

  • 在主串中找到与模式串相同的子串,并返回其所在位置。
  • 子串:主串的一部分,一定存在
  • 模式串:不一定能在主串中找到
  • 要掌握朴素模式匹配算法、KMP算法两种方法

4.2朴素模式匹配算法(两种实现方法):

  • 将主串中所有长度为m的子串依次与模式串对比,直到找到一个完全匹配的子串,或所有的子串都不匹配为止。
  • 主串长度为n,模式串长度为 m,最多对比 n-m+1 个子串
  • 上节讲的index定位操作就是朴素模式匹配算法中其中一种实现方法
  • 也可以使用两个指针i和j来进行匹配。若当前子串匹配失败,则主串指针 i 指向下一个子串的第一个位置,模式串指针 j 回到模式串的第一个位置,即i = i - j + 2; j = 1;
  • 若 j > T.length,则当前子串匹配成功,返回当前子串第一个字符的位置即i - T.length

image.gif 编辑

设主串长度为 n,模式串长度为 m,则最坏时间复杂度 = O(n*m),最好时间复杂度 = O(n)

image.gif

朴素模式匹配算法代码实现:
int Index(SString S, SString T){
    int i=1;                //扫描主串S
    int j=1;                //扫描模式串T
    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;
    else
        return 0;
}
image.gif

5.KMP算法

5.1KMP算法的概念

  • 由D.E.Knuth,J.H.Morris和V.R.Pratt提出,因此称为 KMP算法
  • 是对朴素模式匹配算法的优化
  • 优化的原理就是减少了i指针的回溯,通过已经计算好的next指针,提高算法的整体运行效率

next数组记录了当第几个元素匹配失败时候,j的取值例如:

  • 对于模式串 T = ‘abaabc’
  • 当第6个元素匹配失败时,可令主串指针 i 不变,模式串指针 j=3
  • 当第5个元素匹配失败时,可令主串指针 i 不变,模式串指针 j=2
  • 当第4个元素匹配失败时,可令主串指针 i 不变,模式串指针 j=2
  • 当第3个元素匹配失败时,可令主串指针 i 不变,模式串指针 j=1
  • 当第2个元素匹配失败时,可令主串指针 i 不变,模式串指针 j=1
  • 当第1个元素匹配失败时,匹配下一个相邻子串,令 j=0, i++, j++

next数组只和短短的模式串有关,和长长的主串无关

5.2KMP算法的优点

  • 之所以只和模式串有关,是因为如果在哪里匹配失败,同时说明在这之前的部分主串和模式串是相同的
  • KMP算法,最坏时间复杂度 O(m+n),其中,求 next 数组时间复杂度 O(m),模式匹配过程最坏时间复杂度 O(n)
  • KMP算法精髓:利用好已经匹配过的模式串的信息

image.gif 5.3KMP算法代码实现:

int Index_KMP(SString S, SString T, int next[]){
    int i=1;     //主串
    int j=1;     //模式串
    while(i<S.length && j<=T.length){
        if(j==0 || S.ch[i]==T.ch[j]){      //第一个元素匹配失败时
            ++j;
            ++i;         //继续比较后继字符
        }
        else
            j=next[j]   //模式串向右移动
    }
    if(j>T.length)
        return i-T.length; //匹配成功
}
image.gif

5.4KMP算法之求next数组

image.gif 编辑

5.4.1求next数组代码实现 [含图解]

image.gif 编辑

如上图next数组的求法:
对于任何模式串,当第1个字符不匹配时,只能匹配下一个子串,因此,next[1] = 0——表示模式串应右移一位,主串当前指针后移一位,再和模式串的第一字符进行比较;
int Index_KMP(SString S, SString T, int next[]){
    int i=1;     //主串
    int j=1;     //模式串
    while(i<S.length && j<=T.length){
        if(j==0 || S.ch[i]==T.ch[j]){      //第一个元素匹配失败时
            ++j;
            ++i;         //继续比较后继字符
        }
        else
            j=next[j]   //模式串向右移动
    }
    if(j>T.length)
        return i-T.length; //匹配成功
}

image.gif

5.4.1next数组的作用:

  • 当模式串的第 j 个字符失配时,从模式串的第 next[j] 的继续往后匹配

5.5KMP算法之求nextval数组

定义:

  • nextval数组是对next数组的优化,用nextval替代next数组,减少了无意义的对比

nextval数组的求法:

  • 先根据上面的方法算出next数组
  • 先令nextval[1]=0
  • 再根据下面代码算出后面的nextval数组

求nextval数组代码实现[此处本人理解可能有点小问题,但是问题不大;理论任然成立]

for(int j = 2; j <= T.length; j++)
{
    //让第next值个元素的值和当前元素比较
    if(T.ch[next[j]] == T.ch[j])
    {
        //若相等则让第next值个元素的nextval值复制给当前元素的nextval值
        nextval[j] = nextval[next[j]];
    }
    else
    {
        //若不等则让当前元素的next值赋值给当前元素的nextval值
        nextval[j] = next[j];
    }
}
image.gif


相关文章
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
【EMNLP2024】基于多轮课程学习的大语言模型蒸馏算法 TAPIR
阿里云人工智能平台 PAI 与复旦大学王鹏教授团队合作,在自然语言处理顶级会议 EMNLP 2024 上发表论文《Distilling Instruction-following Abilities of Large Language Models with Task-aware Curriculum Planning》。
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
3天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
109 80
|
22天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
28天前
|
机器学习/深度学习 算法 Serverless
基于WOA-SVM的乳腺癌数据分类识别算法matlab仿真,对比BP神经网络和SVM
本项目利用鲸鱼优化算法(WOA)优化支持向量机(SVM)参数,针对乳腺癌早期诊断问题,通过MATLAB 2022a实现。核心代码包括参数初始化、目标函数计算、位置更新等步骤,并附有详细中文注释及操作视频。实验结果显示,WOA-SVM在提高分类精度和泛化能力方面表现出色,为乳腺癌的早期诊断提供了有效的技术支持。
|
8天前
|
供应链 算法 调度
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。
|
15天前
|
存储 算法
基于HMM隐马尔可夫模型的金融数据预测算法matlab仿真
本项目基于HMM模型实现金融数据预测,包括模型训练与预测两部分。在MATLAB2022A上运行,通过计算状态转移和观测概率预测未来值,并绘制了预测值、真实值及预测误差的对比图。HMM模型适用于金融市场的时间序列分析,能够有效捕捉隐藏状态及其转换规律,为金融预测提供有力工具。
|
24天前
|
算法
基于GA遗传算法的PID控制器参数优化matlab建模与仿真
本项目基于遗传算法(GA)优化PID控制器参数,通过空间状态方程构建控制对象,自定义GA的选择、交叉、变异过程,以提高PID控制性能。与使用通用GA工具箱相比,此方法更灵活、针对性强。MATLAB2022A环境下测试,展示了GA优化前后PID控制效果的显著差异。核心代码实现了遗传算法的迭代优化过程,最终通过适应度函数评估并选择了最优PID参数,显著提升了系统响应速度和稳定性。
105 15
|
15天前
|
机器学习/深度学习 算法 信息无障碍
基于GoogleNet深度学习网络的手语识别算法matlab仿真
本项目展示了基于GoogleNet的深度学习手语识别算法,使用Matlab2022a实现。通过卷积神经网络(CNN)识别手语手势,如&quot;How are you&quot;、&quot;I am fine&quot;、&quot;I love you&quot;等。核心在于Inception模块,通过多尺度处理和1x1卷积减少计算量,提高效率。项目附带完整代码及操作视频。
|
21天前
|
算法
基于WOA鲸鱼优化的购售电收益与风险评估算法matlab仿真
本研究提出了一种基于鲸鱼优化算法(WOA)的购售电收益与风险评估算法。通过将售电公司购售电收益风险计算公式作为WOA的目标函数,经过迭代优化计算出最优购电策略。实验结果表明,在迭代次数超过10次后,风险价值收益优化值达到1715.1万元的最大值。WOA还确定了中长期市场、现货市场及可再生能源等不同市场的最优购电量,验证了算法的有效性。核心程序使用MATLAB2022a实现,通过多次迭代优化,实现了售电公司收益最大化和风险最小化的目标。

热门文章

最新文章