数据结构之串

数据结构之串

  • 1、串的定义及基本运算
  • 2、串的存储结构
  • 3、串的模式匹配

  数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发,分析和研究计算机加工的数据的特性,以便为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作方法,为提高利用计算机解决问题的效率服务。
  数据结构是指数据元素的集合及元素间的相互关系和构造方法。元素之间的相互关系是数据的 逻辑结构,数据元素及元素之间关系的存储称为 存储结构(或物理结构)。数据结构按照逻辑关系的不同分为 线性结构非线性结构两大类,其中,非线性结构又可分为树结构和图结构。
  线性结构是一种基本的数据结构,主要用于对客观世界中具有单一前驱和后继的数据关系进行描述。线性结构的特点是数据元素之间呈现一种线性关系,即元素“一个接一个排列”。
  串(字符串)是一种特殊的线性表,其数据元素为字符。计算机中非数值问题处理的对象经常是字符串数据,例如,在汇编和高级语言的编译程序中,源程序和目标程序都是字符串;在事处理程序中,姓名、地址等一般也是作为字符串处理的。串具有自身的特性,运算时常常把一个串作为一个整体来处理。这里介绍串的定义、基本运算、存储结构及串的模式匹配算法。

1、串的定义及基本运算

  (1)串的定义
  串是仅由字符构成的有限序列,是一种线性表。一般记为 S=‘a1a2…an’,其中,S是串名,单引号括起来的字符序列是串值。
  (2)串的几个基本概念
  ●空串:长度为零的串称为空串,空串不包含任何字符。
  ●空格串:由一个或多个空格组成的串。虽然空格是一个空白字符,但它也是一个字符,在计算串长度时要将其计算在内。
  ●子串:由串中任意长度的连续字符构成的序列称为子串。含有子串的串称为主串。子串在主串中的位置是指子串首次出现时,该子串的第一个字符在主串中的位置。空串是任意串的子串。
  ●串相等:指两个串长度相等且对应序号的字符也相同。
  ●串比较:两个串比较大小时以字符的 ASCII码值(或其他字符编码集合)作为依据。实质上,比较操作从两个串的第一个字符开始进行,字符的码值大者所在的串为大;若其中一个串先结束,则以串长较大者为大。
  (3)串的基本操作
  ① 赋值操作 StrAssign(s,t): 将串 s 的值赋给串t。
  ② 连接操作 Concat(s,t): 将串 t 接续在串 s 的尾部,形成一个新串。
  ③ 求串长 StrLength(s): 返回串 s 的长度。
  ④ 串比较 StrCompares,t): 比较两个串的大小。返回值-1、0 和1分别表示 s<t、s=t 和
s>t三种情况。
  ⑤ 求子串 SubString(s,start,len): 返回串s 中从 start 开始的、长度为 len 的字符序列。
  以上 5 种最基本的串操作构成了串的最小操作子集,利用它们可以实现串的其他运算。

2、串的存储结构

  串可以进行顺序存储或链式存储。
  (1)串的顺序存储结构。 串的顺序存储结构是指用一组地址连续的存储单元来存储串值的字符序列。由于串中的元素为字符,所以可通过程序语言提供的字符数组定义串的存储空间,也可以根据串长的需要动态申请字符串的空间。
  (2)串的链式存储。当用链表存储串中的字符时,每个结点中可以存储一个字符,也可以存储多个字符,此时要考虑存储密度问题。在链式存储结构中,结点大小的选择会直接影响对串的处理效率。

3、串的模式匹配

  子串的定位操作通常称为串的模式匹配,它是各种串处理系统中最重要的运算之一。子串也称为模式串。
  (1)补素的模式匹配算法
  该算法也称为布鲁特- 福斯算法,其基本思想是从主串的第一个字符起与模式串的第一个字符比较,若相等,则继续逐一对字符进行后续的比较,否则从主串第二个字符起与模式串第一个字符重新比较,直到模式串中每个字符依次和主串中一个连续的字符序列相等时为止,此时称为匹配成功。如果不能在主串中找到与模式串相同的子串,则匹配失败。
  【函数】以字符数组存储字符串,实现补素的模式匹配算法。

int Index(char S[], char T[], int pos)
/*查找并返回模式串T在主串S中从pos 开始的位置(下标),若T不是S的子串,则返回-1*/
/*模式串T和主S第一个字符的下标为0*/
{
	int  i, j, slen, tlen;
	i=pos; j=0;								/*i、j分别用于指出主串字符和模式串字符的位置*/
	slen = strlen(S); tlen = strlen(T);		/*计算主串和模式串的长度*/
	while (i < slen && j< tlen){
		if(S[i == T[j]){i++; j++;}
		else {
			i=i-j+1;						/*主串字符的位置指针回退*/
			j=0;
		}
	}/*while*/
	if (j >= tlen) return i - tlen;
	return -1;
}/*Index*/

  假设主串和模式串的长度分别为 n 和 m,位置序号从0开始计算,下面分析朴素模式匹配算法的时间复杂度。设从主串的第 i 个位置开始与模式串匹配成功,且在前 i 趟匹配中(位置0 ~ i-1),每趟不成功的匹配都是模式串的第一个字符与主串中相应的字符不相同,则在前 i 趟匹配中,字符的比较共进行了 i 次,而第 i+1 趟(从位置 i 开始)成功匹配的字符比较次数为m,所以总的字符比较次数为 i+m(0≤i≤n-m)。若在主串的 n-m 个起始位置上匹配成功的概率相同,则在最好情况下,匹配成功时字符间的平均比较次数为
Σ i = 0 n − m P i ( i + m ) = 1 n − m + 1 Σ i = 0 n − m ( i + m ) = 1 2 ( n + m ) {\huge\Sigma}^{n-m}_{i=0}P_i(i+m) = \frac1{n-m+1} {\huge\Sigma}^{n-m}_{i=0}(i+m) = \frac 12(n+m) Σi=0nmPi(i+m)=nm+11Σi=0nm(i+m)=21(n+m)
  因此,在最好情况下匹配算法的时间复杂度为 O(n+m)。
  而在最坏情况下,每一趟不成功的匹配都是模式串的最后一个字符与主串中相应的字符不相等,则主串中新一趟匹配过程的起始位置为 i-m+2。设从主串的第 i 个字符开始匹配时成功,则在前 i 趟不成功的匹配中,每趟都比较了 m 次,总共比较了i×m 次,第 i+1 趟的成功匹配也比较了 m 次。因此,最坏情况下的平均比较次数为
Σ i = 0 n − m P i ( ( i + 1 ) × m ) = m n − m + 1 Σ i = 0 n − m ( i + 1 ) = 1 2 m ( n − m + 2 ) {\huge\Sigma}^{n-m}_{i=0}P_i((i+1)×m) = \frac m{n-m+1} {\huge\Sigma}^{n-m}_{i=0}(i+1) = \frac 12m(n-m+2) Σi=0nmPi((i+1)×m)=nm+1mΣi=0nm(i+1)=21m(nm+2)
  通常情况下,由于n>>m,所以该算法在最环情况下的时间复杂度为 O(nXm)。
  (2)改进的模式匹配算法
  改进的模式匹配算法又称为 KMP 算法,其改进之处在于:每当匹配过程中出现相比较的字符不相等时,不需要回退主串的字符位置指针,而是利用已经得到的“部分匹配”结果将模式串向右“滑动”尽可能远的距离,再继续进行比较。
  设模式串为”p0…pm-1”,KMP 匹配算法的思想是:当模式串中的字符 pj 与主串中相应的字符 Si 不相等时,因其前 j 个字符(“p0…pj-1”)已经获得了成功的匹配,所以若模式串中的”p0…pk-1”与"pj-k…pj-1"相同,这时可令 Pk 与 Si 进行比较,从而使 i 无须回退。
  在KMP算法中,依据模式串的next函数值实现子串的滑动。若令 next[j]=k,则next[j] 表示当模式串中的 pj 与主串中相应字符不相等时,令模式串的 Pnext[j]与主串的相应字符进行比较。
  next函数的定义如下:
在这里插入图片描述

  【函数】求模式串的next函数

void Get_next(char *p, int next[])	/*求模式串p的next函数值并存入数组 next*/
{
	int i, j, slen;
	slen = strlen(p); i= 0;
	next[0]=-1; j=-1;
	while(i < slen){
		if(j=-l || p[i] ==p[j]) {++i; ++j; next[i] =j;}
		else j= next[i];
	}/*while*/
}/*Get_next*/

  【函数】KMP 模式匹配算法,设模式串第一个字符的下标为 0

int Index_KMP(char *s, char *p,int pos, int next[] )
/*利用模式串p的next 函数,求p在主串s中从第pos个字符开始的位置*/
/*若匹配成功,返回模式串在主串中的位置(下标),否则返回-1*/
{
	int i, j, slen, plen;
	i= pos-1;
	i=-1;
	slen = strlen(s);plen = strlen(p);
	while (i < slen &&j< plen ) {
		if(j==-1 || s[i]==p[j]) {++i;++j;}
		else j = next[j];
	}/*while*/
	if (j>=plen) return i - plen;
	else return -1;
}/*Index_KMP*/

  例如,设主串为“abacbcabababbcbc”,模式串为“abababb”,且模式串的 next 函数值如下表所示,则KMP 算法的匹配过程如下图所示。其中,i 是主串字符的下标,j 是模式串字符的下标。

j0    1    2    3    4    5  6  
模式串a    b    a    b    a    bb
next[j]-1    0    0    1    2    34

在这里插入图片描述

  第一趟匹配从 S[0]与 P[0]开始。由于 S[0] == P[0]、S[1]==P[1]、S[2]==P[2],所以接下来比较S[3]与P[3],由于S[3]与 P[3]不相等,所以第一趟结束,要进行第二趟匹配,令j=next [3] (即j=1)。第二趟从 S[3]与 P[1]开始比较,仍不相等,因此第二趟结束,要进行第三趟匹配,所以令 j = next[1] (即j=0)。 第三趟从 S[3]与 P[0]开始比较,如上图 (a) 所示。由于 S[3]与P[0]不相等,所以令j=next[0] (即j= -1), 此时满足条件“j == -1”,显然不能令S[3]与 P[-1]进行比较,说明主串中从i=3 开始的子串不可能与模式串相同,因此需要将 i 的值递增后再继续进行匹配过程,即令 i++、j++,然后下一趟从 S[4] 与 P[0] 开始比较,如上图 (b)所示,继续匹配过程。直到某一趟匹配成功,或者由于在主串中找不到模式串而以失败结束。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

16bit半精度浮点加乘法(用于结果验证)-图形测试小程序(python)

测试&#xff1a; 代码如下&#xff1a; import tkinter as tk import struct from tkinter import Entry, Button, Labeldef float_to_binary_16(value):# 将浮点数转换为16位二进制表示binary_representation struct.pack(!e, value)binary_string .join(f{byte:08b} for…

Ubuntu20.4 Mono C# gtk 编程习练笔记(二)

界面设计习练后&#xff0c;下面写一些程序设计心得。 程序结构 先看一下程序总体结构&#xff0c;先在program.cs中找到main入口&#xff0c;在命名空间下是MainClass类&#xff0c;Main函数进入后首先建立应用程序环境 Application.Init&#xff0c;然后对MainWindow进行实…

css实现动态水波纹效果

效果如下&#xff1a; 外层容器 (shop_wrap)&#xff1a; 设置外边距 (padding) 提供一些间距和边距 圆形容器 (TheCircle)&#xff1a; 使用相对定位 (position: relative)&#xff0c;宽度和高度均为 180px&#xff0c;形成一个圆形按钮圆角半径 (border-radius) 设置为 50%&…

【性能调优】local模式下flink处理离线任务能力分析

文章目录 一. flink的内存管理1.Jobmanager的内存模型2.TaskManager的内存模型2.1. 模型说明2.2. 通讯、数据传输方面2.3. 框架、任务堆外内存2.4. 托管内存 3.任务分析 二. 单个节点的带宽瓶颈1. 带宽相关理论2. 使用speedtest-cli 测试带宽3. 任务分析3. 其他工具使用介绍 本…

生物识别规划人脸识别芯片方案的概述和特点

方案概述 人脸识别方案采用高性能AI芯片&#xff0c;支持RGB和IR摄像头&#xff0c; 支持LCD显示屏。 方案特点 • 普通RGB摄像头和IR摄像头同时参与3D成像RGB摄像头 支持屏幕回显 • 双目摄像头得到特征点视差计算人脸相 对3D深度信息&#xff0c; 同时利用可见光和红外 光谱信…

达梦数据库入门语法:从基础到进阶的指南

目录 博客前言&#xff1a; 达梦数据库语法介绍 一.创建表空间 1.图形化创建 2.语法创建 ​编辑​编辑 3.修改表空间参数 图形化修改 ​编辑​编辑 语法修改 4.设置加密算法、密码 二.创建用户 1.图形化 2.sql执行 ​编辑 3.授予权限 授予用户 DBA 权限 授予用户…

运算符和表达式

表达式 表达式是由运算符、运算量和标点符号组成的有效序列&#xff0c;其目的是用来说明一个计算过程&#xff0c;表达式可以独立成句&#xff0c;一般形式为&#xff1a; 表达式&#xff1b; 运算符 运算符可以按照功能分为&#xff1a;算术运算符、赋值运算符、关系运算…

【 文本到上下文 #4】NLP 与 ML

一、说明 欢迎回到我们的 NLP 博客系列&#xff01;当我们进入第四部分时&#xff0c;焦点转移到机器学习 &#xff08;ML&#xff09; 和自然语言处理 &#xff08;NLP&#xff09; 之间的动态相互作用上。在本章中&#xff0c;我们将深入探讨 ML 和 NLP 的迷人协同作用&#…

PLSQL 把多个字段转为json格式

PLSQL 把多个字段转为json格式 sql Select cc.bm, cc.xm, json_arrayagg(cc.hb) jgFrom (Select aa.bm, aa.xm, json_object(aa.ksbh, aa.wjmc) hbFrom (Select 001 bm, 老六 xm, 0001 ksbh, 文具盒 wjmcFrom dual tUnion AllSelect 001 bm, 老六 xm, 0002 ksbh, 毛笔 wjmcFr…

LabVIEW精确测量产品中按键力和行程

项目背景 传统的按键测试方法涉及手工操作&#xff0c;导致不一致和效率低下。在汽车行业中&#xff0c;带有实体按键的控制面板非常常见&#xff0c;确保一致的按键质量至关重要。制造商经常在这些组件的大规模、准确测试中遇到困难。显然&#xff0c;需要一个更自动化、精确…

Modbus协议学习第三篇之协议通信规则

导语 本篇博客将深入介绍Modbus协议的一些内容&#xff0c;主要包括通讯方式和通讯模型的介绍 Modbus通讯方式 Modbus协议是单主机、多从机的通信协议&#xff0c;即同一时间&#xff0c;总线上只能有一个主设备&#xff0c;但可以有一个或者多个从设备&#xff08;最多好像是2…

基于springboot+vue的校园管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…

贵阳贵安推进“数字活市”战略成效明显

作者&#xff1a;黄玉叶 近年来&#xff0c;贵阳贵安将数字经济确立为高质量发展的主路径之一&#xff0c;把推进“数字活市”作为实施主战略、实现主定位&#xff0c;特别是建设“数字经济发展创新区核心区”的重要抓手&#xff0c;从改革、发展、民生三个维度纵深推进“数字活…

未来的NAS:连接您的数字生活

未来的NAS&#xff1a;连接您的数字生活 引言 网络附加存储&#xff08;Network Attached Storage&#xff0c;简称NAS&#xff09;是一种通过网络连接的存储设备&#xff0c;用于集中存储和共享数据。传统的NAS设备通常包含一个或多个硬盘驱动器&#xff0c;可以通过局域网连…

数据结构和算法的部分例题(力扣)

1.数组 1.1 合并一个数组的两个有序区间 public class MargTwo {public static void main(String[] args) {int[] arr1{1,5,6,2,4,10,11};int[] arr2new int[arr1.length];marg2(arr1,0,2,3,6,arr2);}private static void marg2(int[]arr1,int iStar,int iEnd,int jStar,int j…

【机组】通用寄存器单元实验的解密与实战

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《机组 | 模块单元实验》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 ​ 目录 &#x1f33a;一、 实验目…

广和通AI解决方案“智”赋室外机器人迈向新天地!

大模型趋势下&#xff0c;行业机器人将具备更完善的交互与自主能力&#xff0c;逐步迈向AI 2.0时代&#xff0c;成为人工智能技术全面爆发的重要基础。随着行业智能化&#xff0c;更多机器人应用将从“室内”走向“室外”&#xff0c;承担更多高风险、高智能工作。复杂的室外环…

阿里云国外服务器价格表

阿里云国外服务器优惠活动「全球云服务器精选特惠」&#xff0c;国外服务器租用价格24元一个月起&#xff0c;免备案适合搭建网站&#xff0c;部署独立站等业务场景&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云国外服务器优惠活动&#xff1a; 全球云服务器精选特惠…

Linux网络引导自动安装centos7

目录 一、部署PXE远程安装服务 1. 系统装机的三种引导方式 2. pxe概述 3. 实现过程 4. 搭建过程中服务介绍 4.1 TFTP服务 4.2 vsftp&#xff1a;安装系统镜像文件获取方式 4.3 syslinux 4.4 DHCP服务 5. 操作过程 二、实现Kickstart无人值守安装 1. 安装Kickstart图…

Codeforce s Round 920 (Div. 3) G题 旋转矩阵,斜缀和,平移

Problem - G - Codeforces 目录 题意&#xff1a; 思路&#xff1a; 总思路&#xff1a; 旋转矩阵&#xff1a; 前缀和预处理&#xff1a; 平移的处理&#xff0c;尤其是越界的处理&#xff1a; 核心代码&#xff1a; 题意&#xff1a; 给你个n*m的矩阵&#xff0c;里…