数据结构与算法·第4章【串】

news2024/11/25 6:59:17

串是有限长的字符序列,由一对单引号相括,如: “a string”
可以理解为c++的 s t r i n g string string

基本操作

在这里插入图片描述
在这里插入图片描述
S t r A s s i g n , S t r C o m p a r e , S t r L e n g t h , C o n c a t , S u b S t r i n g StrAssign,StrCompare,StrLength,Concat,SubString StrAssign,StrCompare,StrLength,Concat,SubString是基本操作集

定长顺序存储表示

  #define  MAXSTRLEN  255  // 用户可在255以内定义最大串长
  typedef unsigned char Sstring[MAXSTRLEN + 1];   // 0号单元存放串的长度

就是用了char数组模拟string,只不过在数组首位放了数组长度
串的实际长度可在这个予定义长度的范围内随意设定,超过予定义长度的串值则被舍去,称之为“截断”

基本操作

Status SubString(SString &Sub, SString S, int pos, int len) {
    // 用Sub返回串S的第pos个字符起长度为len的子串。
    //其中,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-//pos+1 。
    if ( pos<1 ||  pos>S[0] || len<0 || len>S[0]-pos+1 )
             return ERROR;
    Sub[1..len] = S[pos..pos+len-1];
    Sub[0] = len;           return OK;
}//SubString

注意S[0]-pos+1这里需要+1

堆分配存储表示

typedef struct {
   char *ch;      // 若是非空串,则按串长分配存储区,否则ch为NULL
   int  length;   // 串长度
} HString;

通常,C语言中提供的串类型就是以这种存储方式实现的。系统利用函数malloc( )和free( )进行串值空间的动态管理,为每一个新产生的串分配一个存储区,称串值共享的存储空间为“堆”。C语言中的串以一个空字符为结束符, 串长是一个隐含值。简而言之:通过malloc(),free()为串动态分配存储空间

基本操作

Status StrInsert(HString &S, int pos, HString T) {
      // 1≤pos≤StrLength(S)+1。
       //在串S的第pos个字符之前插入T
      if (pos<1 || pos>S.length+1 ) return ERROR; 
      // pos不合法
      if (T.length) {
      //T非空,则重新分配空间,插入T 
      if (!(S.ch = (char *) realloc ( S.ch, ( S.length+T.length ) * sizeof ( char ))))
          exit (OVERFLOW);
      for ( i=S.length-1;i>=pos-1; --i)
      //为插入T而腾出位置
      S.ch[i+T.length] = S.ch[i];
      S.ch[pos-1..pos+T.length-2] = T.ch[0..T.length-1]//插入T
      S.Length += T.length;
   }
   return OK;
} // StrInsert

注意这一步中的S.ch[pos-1..pos+T.length-2],感觉这些细节其实不那么能注意到
这里i=S.length-1,是因为:pos给出的视角是数组从1开始到 l e n g t h length length的存储 [ 1 ] … … [ l e n g t h ] [1]……[length] [1]……[length],而实际上堆分配的串的存储应该是从0开始的 [ 0 ] … … [ l e n g t h − 1 ] [0]……[length-1] [0]……[length1]

r e a l l o c ( ) realloc() realloc()

  • 如果 size 的值为 0,则等价于调用 free(ptr),即释放 ptr 所指向的内存空间。
  • 如果传入的 ptr 不为 NULL,并且 size 大于原先分配的内存大小,则尝试将之前分配的内存空间扩展为 size 字节的大小。如果当前内存不足以扩展到 size 字节,则重新分配一块新的内存空间,并将原有空间中的数据复制到新的内存空间上,最后释放原有的内存空间,返回新的内存空间的地址。
  • 如果传入的 ptr 不为 NULL,并且 size 小于或等于原先分配的内存大小,则尝试缩小原有的内存空间到指定的大小。如果原有的内存空间过大,多余的部分会被返回给内存管理系统。
Status SubString(HString& Sub, HString S, int pos, int len) {
    // 用 Sub 返回串 S 的第 pos 个字符起长度为 len 的子串
    if (pos < 1 || pos > S.length || len < 0 || len > S.length - pos + 1) return ERROR;
    if (Sub.ch) free(Sub.ch); // 释放旧空间
    if (!len) {
        Sub.ch = NULL;
        Sub.length = 0; // 空子串
    } else {
        Sub.ch = (char*)malloc(len * sizeof(char)); // 完整子串
        for (int i = 0; i < len; i++) Sub.ch[i] = S.ch[pos + i - 1];
        Sub.length = len;
    }
    return OK;
} // SubString

仍然要强调的是,注意特殊情况进行特殊判断

串的块链存储表示

链表来存储串值,由于串的数据元素是一个字符,因此用链表存储时,通常一个结点中可以存放一个字符,也可以存放多个字符。

在这里插入图片描述

#define CHUNKSIZE 80  // 可由用户定义的块大小
typedef struct Chunk {
    char ch[CHUNKSIZE];
    struct Chunk* next;
} Chunk;
typedef struct {
    Chunk *head, *tail; // 串的头和尾指针
    int curlen;         // 串的当前长度
} LString;

实际应用时,可以根据问题所需来设置结点的大小。
例如: 在编辑系统中,整个文本编辑区可以看成是一个串,每一行是一个子串,构成一个结点。即: 同一行的串用定长结构(80个字符), 行和行之间用指针相联接。

串的模式匹配算法

朴素模式匹配

int Index(SString S, SString T, int pos) {
    // 返回子串 T 在主串 S 中第 pos 个字符之后的位置。若不存在,
    // 则函数值为 0。其中,T 非空,1 <= pos <= StrLength(S)。
    i = pos;
    j = 1;
    while (i <= S[0] && j <= T[0]) { // 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;
} // Index

关于 i = i − j + 2 i = i - j + 2 i=ij+2 的含义:当在匹配中出现了不匹配的情况时,我们需要将指针 i i i j j j 同时后移一位再进行匹配,以尝试匹配剩下的部分。由于当前指针 i 已经匹配过了前 j − 1 j - 1 j1个字符,因此需要将 i 前移 j − 1 - 1 1 位,再加上 2 2 2,即可保证 i i i恰好后移一位,准备与 j j j 再次匹配。

这种位置类的细节,完全值得好好注意虽然暂时还不知道考试会不会扣这方面的细节,但是自己写代码的时候,也需要避免越界访问

时间复杂度为:O(m*n)

KMP算法

int Index_KMP(SString S, SString T, int pos) {
    // 利用模式串 T 的 next 函数求 T 在主串 S 中第 pos 个字符之后的位置的 KMP 算法。
    // 其中,T 非空,1 ≤ pos ≤ StrLength(S)
    int next[MAXSIZE];
    GetNext(T, next);
    int i = pos;
    int j = 1;
    while (i <= S[0] && j <= T[0]) { // 0 下标存储字符串长度
        if (j == 0 || S[i] == T[j]) { 
            ++i;  
            ++j; // 继续比较后继字符
        } else {
            j = next[j]; // 模式串向右移动
        }
    }
    if (j > T[0]) {
        return i - T[0] + 1; // 匹配成功
    } else {
        return 0;
    }
} // Index_KMP

这个算法稍微有点复杂
讲解
其中,next数组要自己弄出来

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/613229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据技术——使用IDEA开发Scala程序

目录 一、使用IDEA开发WordCount程序... 3 二、实验目的... 3 三、实验要求... 3 四、实验环境... 3 五、实验步骤... 3 4.1.1启动IDEA并创建一个新项目WordCount 3 4.1.2为WordCount项目添加Scala框架支持... 7 4.1.3数据准备... 8 4.1.4设置项目目录... 9 4.1.5新建…

webAPI学习笔记4——PC端网页特效

目录 1. 元素偏移量 offset 系列 1.1 offset 概述 1.2 offset 与 style 区别 offset style !!&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;案例&#xff1a;获取鼠标在盒子内的坐标 &#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…

Jeston Orin Nnao 安装pytorch与torchvision环境

大家好&#xff0c;我是虎哥&#xff0c;Jeston Orin nano 8G模块&#xff0c;提供高达 40 TOPS 的 AI 算力&#xff0c;安装好了Jetpack5.1之后&#xff0c;我们需要配置一些支持环境&#xff0c;来为我们后续的深度学习开发提供支持。本章内容&#xff0c;我将主要围绕安装对…

OCR图片文字识别,人工手动图片标注软件安装过程

OCR图片文字识别&#xff0c;人工手动图片标注软件安装过程&#xff0c;本章关注标注软件的安装&#xff0c;启动过程 1. 下载 anaconda anaconda 下载慢的问题&#xff1a; 使用国内镜像地址下载&#xff1a; https://mirrors.bfsu.edu.cn/anaconda/archive/ https://www.ana…

OpenMMLab-AI实战营第二期——4.深度学习预训练与MMPretrain

文章目录 1. MMPreTrain算法库介绍1.1 算法库与任务组成1.2 框架概览 2. 经典主干网络2.1 ResNet2.2 Vision Transformer 3. 自监督学习3.1 SimCLR3.2 MAE3.3 iBOT 4. 多模态算法4.1 CLIP4.2 BLIP 视频链接&#xff1a;b站-深度学习预训练与MMPretrain 1. MMPreTrain算法库介绍…

NvM学习笔记(一)以TC387为例,分析为什么要使用Flash 模拟 EEPROM ?

在嵌入式软件系统中&#xff0c;管理非易失性的数据存储&#xff0c;如在系统启动时&#xff0c;从非易失性存储器中读取一些关键数据&#xff0c;在系统关闭阶段&#xff0c;同步应用程序RAM区的数据到非易失性存储器中&#xff0c;是一项十分必要的工作。 目前行业内用的最广…

Linux :: 时间日历指令【3】:cal 指令:查询当日是今年的第几天、输出当前月历、指定月历、输出当前年历、指定年历

前言&#xff1a;本篇是 Linux 基本操作篇章的内容&#xff01; 笔者使用的环境是基于腾讯云服务器&#xff1a;CentOS 7.6 64bit。 学习集&#xff1a; C 入门到入土&#xff01;&#xff01;&#xff01;学习合集Linux 从命令到网络再到内核&#xff01;学习合集 目录索引&am…

Redis分段锁实现超高并发秒杀

参考尼恩著&#xff1a;《Java高并发核心编程》 技术自由圈 业务情景 还是秒杀场景&#xff0c;假设抖音直播间小杨哥上架6000单螺蛳粉&#xff0c;价格9.9买10包&#xff0c;限时1分钟秒杀&#xff0c;此时准备秒杀的人有1万人。我们首先从技术上来看看如果不进行优化是否可以…

控制四旋翼飞行器以进行多目标航点导航的MPC算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

信不信,3招就能测出你的网工水平

大家好&#xff0c;我的网工朋友 老话常谈一下&#xff0c;在网工这行发展&#xff0c;技术肯定是第一位的。 从你入行的第一步起&#xff0c;就很看重你的技术水平了&#xff0c;越往后&#xff0c;就更注重技术水平和项目经验的融合度。 再往后&#xff0c;技术要有&#…

网络安全实验室|网络信息安全攻防学习平台(脚本关1-6)

传送门&#xff1a; http://hackinglab.cn/ 1. key又又不见了 点击此处开启抓包&#xff0c;send ti repeater 模块 yougotit_script_now2. 快速口算 脚本来源&#xff1a; https://blog.csdn.net/hzxtjx/article/details/125692349 import requests,re# 自动处理cookies&a…

【PCB专题】案例:PCB封装中哪些禁布区我们最常容易忘记增加

USB等直插器件焊接面禁布区 USB器件面那大家都知道有座子有自己的Place_Bound。不同的器件如果Place_Bound重叠的话会报DRC。 但是因为器件是只在一个面上,另一个面是焊接脚,或是另一面不是焊接脚,但PCB封装上为通孔。比如有一些器件从PCB上看是通孔,但PCB Layout人员没见…

c#如何将数据缓存至Redis

环境准备 首先肯定是需要安装redis啦&#xff01;这是我跑在docker的redis&#xff0c;和安装在本地的是 一样的效果 可视化工具Redis Desktop Manager。 使用方法 第一步&#xff0c;安装nuget包 Microsoft.Extensions.Caching.StackExchangRedis 创建一个asp.net.core项目…

Ubuntu20.04 终端打开不了的问题排查

Ubuntu20.04 终端打开不了的问题排查 今天用virtualbox安装了ubuntu20.04 问题&#xff1a;右键打开终端&#xff0c;怎么也打开不了&#xff01; 点了也没反应&#xff0c;或者鼠标转小圈圈&#xff0c;然后也没有反应… 解决方法&#xff1a; 1、Ctrl Alt F6 先切换到终…

ChatGPT:求求你憋再问我关于C++多态的任何问题了...

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f337;多态在继承中的表现&#x1f33a;虚函数的重写&#x1f33a;虚函数重写的两个例外&#x1f3f5;️1.协变&#x1f3f5;️2.析构函数的重写 &#x1f33a;C11 override 和 final关键字&#x1f3f5;️final&am…

msvcr110.dll丢失怎么修复

msvcr110.dll是Microsoft Visual C 2012 Redistributable的一部分&#xff0c;它是一种动态链接库&#xff08;DLL&#xff09;&#xff0c;旨在存储许多Microsoft Visual C应用程序共享的功能。这些功能包括数学运算、字符串处理、内存分配和释放等。它在Windows操作系统中起着…

精通Java数组的艺术:从初学者到高手的进阶之路(一)

⭐ 数组⭐ 数组的定义⭐ 创建数组和初始化⭐ 数组常见操作⭐ 数组的遍历⭐ for-each 循环⭐ 数组的拷贝⭐ java.util.Arrays 类 ⭐ 数组 数组的概念 ⭐ 数组的定义 数组是相同类型数据的有序集合。其中&#xff0c;每一个数据称作一个元素&#xff0c;每个元素可以通过一个索引…

Python+Selenium 网页自动化 exe 程序编程实现(最全避坑指南)

前言 在我的日常工作中&#xff0c;经常需要在内网&#xff08;不连接互联网&#xff09;的网页版办公系统中进行抓取网页数据、修改表单等大量重复性的操作。我就想是否可以编写出自动化的工具&#xff0c;将这些日常琐碎的操作变得轻松而高效。虽然本人非计算机相关专业&…

OpenGL 纹理

1.简介 纹理是一个2D图片&#xff08;甚至也有1D和3D的纹理&#xff09;&#xff0c;它可以用来添加物体的细节&#xff1b;你可以想象纹理是一张绘有砖块的纸&#xff0c;无缝折叠贴合到你的3D的房子上&#xff0c;这样你的房子看起来就像有砖墙外表了。 为了能够把纹理映射(M…

Day973.授权码许可类型中,为什么一定要有授权码? -OAuth 2.0

授权码许可类型中&#xff0c;为什么一定要有授权码&#xff1f; Hi&#xff0c;我是阿昌&#xff0c;今天学习的是auth2中为什么一定要有授权码的内容。 OAuth 2.0 的授权码许可类型&#xff0c;在小兔打单软件的例子里面&#xff0c;小兔最终是通过访问令牌请求到小明的店铺…