串(4/6)

目录

1. 串的概念及应用实例

1.1 串的定义

1.2 应用实例

2. 串的基本操作

2.1 创建和读取

2.2 串的拼接

2.3 串的比较

2.4 插入和删除

2.5 查找子串

3. 串的存储结构及实现

3.1 顺序存储结构

3.2 链式存储结构

3.3 存储结构的选择

4. 串的模式匹配算法

4.1 朴素匹配算法

4.2 KMP算法

4.3 BM算法

5. 实例分析与实现

5.1 朴素匹配算法的实现

5.2 KMP算法的实现

5.3 BM算法的实现

6. 串处理中的常见问题及优化

6.1 常见问题

6.2 优化建议

7. 总结


1. 串的概念及应用实例

1.1 串的定义

(String),又称字符串,是由零个或多个字符组成的有限序列。通常记为 S="s1s2...sn"S = "s_1s_2...s_n"S="s1​s2​...sn​",其中 sis_isi​ 表示第 iii 个字符,nnn 为串的长度。串在计算机科学中是非常重要的数据结构之一,广泛用于文本处理、数据存储和传输等领域。

1.2 应用实例

串的应用非常广泛,以下是一些常见的应用实例:

  • 文本编辑器:所有文字处理软件(如Microsoft Word)都需要使用字符串来表示和编辑文本内容。
  • 网络数据传输:在网络通信中,数据通常以字符串的形式传输,如HTTP协议中的报文。
  • DNA序列分析:在生物信息学中,DNA序列被视为由字符(A、C、G、T)组成的字符串,用于基因分析和比对。

2. 串的基本操作

串的基本操作包括创建、读取、拼接、比较、插入、删除和查找等操作。下表总结了串的常用基本操作及其时间复杂度:

操作描述时间复杂度
创建串创建一个新的字符串O(n)
读取串读取字符串中的某个字符O(1)
串的拼接将两个字符串连接成一个新字符串O(n+m)
串的比较比较两个字符串的大小O(n)
插入字符在字符串中插入一个或多个字符O(n)
删除字符从字符串中删除一个或多个字符O(n)
查找子串在字符串中查找特定的子串O(n*m)

2.1 创建和读取

创建字符串通常是指将字符序列转换为字符串对象的过程,读取字符串中的字符是指访问字符串中特定位置的字符。创建和读取操作都是非常基础的操作,其时间复杂度分别为 O(n)O(n)O(n) 和 O(1)O(1)O(1)。

2.2 串的拼接

串的拼接操作将两个或多个字符串连接成一个新的字符串。拼接操作的时间复杂度为 O(n+m)O(n+m)O(n+m),其中 nnn 和 mmm 分别是两个字符串的长度。

2.3 串的比较

串的比较操作用于判断两个字符串是否相等,或者判断它们的字典序关系。常见的比较方式是按字符逐一比较,直到找到不同字符或遍历结束。时间复杂度为 O(n)O(n)O(n)。

2.4 插入和删除

插入和删除操作涉及到字符串中字符的增删,时间复杂度为 O(n)O(n)O(n),其中 nnn 为字符串的长度。这是因为插入或删除字符可能需要移动字符串中的其他字符。

2.5 查找子串

查找子串是指在一个字符串中寻找某个特定的子字符串。常用的查找算法包括暴力查找、KMP算法等。暴力查找的时间复杂度为 O(n×m)O(n \times m)O(n×m),其中 nnn 为原串的长度,mmm 为子串的长度。

3. 串的存储结构及实现

串的存储结构主要有两种:顺序存储链式存储

3.1 顺序存储结构

顺序存储结构是将字符串中的字符按顺序存储在连续的存储单元中,常见的实现方式是使用数组或动态数组。

  • 优点:访问速度快,易于实现。
  • 缺点:插入和删除操作较为低效,且可能浪费空间。

3.2 链式存储结构

链式存储结构使用链表来存储字符串中的字符,每个节点存储一个字符及其后续节点的指针。

  • 优点:插入和删除操作效率较高,不会浪费空间。
  • 缺点:访问速度较慢,且实现复杂度较高。

下表对比了顺序存储和链式存储的特点:

存储结构优点缺点
顺序存储访问速度快,易于实现插入删除效率低,空间浪费
链式存储插入删除效率高,不浪费空间访问速度慢,实现复杂

3.3 存储结构的选择

在实际应用中,存储结构的选择通常依赖于具体的需求。如果需要频繁进行插入和删除操作,链式存储结构较为适合;而如果以随机访问为主,顺序存储结构更为高效。

4. 串的模式匹配算法

串的模式匹配问题是在一个字符串中查找另一个字符串(称为模式串)出现的位置。常见的模式匹配算法有:

  • 朴素算法(Brute Force):逐一比较原串中的子串与模式串,时间复杂度为 O(n×m)O(n \times m)O(n×m)。
  • KMP算法(Knuth-Morris-Pratt):通过部分匹配表(Partial Match Table)来加速匹配过程,时间复杂度为 O(n+m)O(n + m)O(n+m)。
  • BM算法(Boyer-Moore):利用模式串的后缀信息进行匹配跳跃,时间复杂度平均为 O(n)O(n)O(n)。

4.1 朴素匹配算法

朴素匹配算法是最基础的模式匹配算法,其思想是从目标串的每个位置开始,逐个字符与模式串比较,如果匹配则继续,否则从下一个位置重新开始匹配。

4.2 KMP算法

KMP算法通过在匹配过程中利用已知信息减少不必要的重复匹配,从而提高匹配效率。它预处理模式串,生成部分匹配表(也称为失配函数表),使得在发生不匹配时可以跳过一定的字符,而不是回溯。

4.3 BM算法

BM算法通过从右向左匹配并利用模式串中的信息来决定匹配失败后应跳过多少字符,通常情况下BM算法的效率高于KMP算法,特别是在长文本中查找短模式串时。

下表总结了三种常见的串匹配算法的特点:

算法时间复杂度适用场景
朴素算法O(n×m)O(n \times m)O(n×m)简单场景,无需预处理
KMP算法O(n+m)O(n + m)O(n+m)长串匹配较高效,需预处理
BM算法O(n)O(n)O(n)短模式串匹配,效率最高

5. 实例分析与实现

5.1 朴素匹配算法的实现

def brute_force_match(text, pattern):n, m = len(text), len(pattern)for i in range(n - m + 1):j = 0while j < m and text[i + j] == pattern[j]:j += 1if j == m:return i  # 匹配成功,返回起始位置return -1  # 匹配失败

5.2 KMP算法的实现

def compute_lps(pattern):m = len(pattern)lps = [0] * mlength = 0i = 1while i < m:if pattern[i] == pattern[length]:length += 1lps[i] = lengthi += 1else:if length != 0:length = lps[length - 1]else:lps[i] = 0i += 1return lpsdef kmp_match(text, pattern):n, m = len(text), len(pattern)lps = compute_lps(pattern)i = j = 0while i < n:if pattern[j] == text[i]:i += 1j += 1if j == m:return i - j  # 匹配成功,返回起始位置elif i < n and pattern[j] != text[i]:if j != 0:j = lps[j - 1]else:i += 1return -1  # 匹配失败

5.3 BM算法的实现

def bm_match(text, pattern):n, m = len(text), len(pattern)bad_char = [-1] * 256for i in range(m):bad_char[ord(pattern[i])] = is = 0while s <= n - m:j = m - 1while j >= 0 and pattern[j] == text[s + j]:j -= 1if j < 0:return s  # 匹配成功,返回起始位置else:s += max(1, j - bad_char[ord(text[s + j])])return -1  # 匹配失败

6. 串处理中的常见问题及优化

6.1 常见问题

在处理串操作时,常见的问题包括:

  • 内存管理问题:对于长字符串的处理,内存消耗较大,需要合理管理内存。
  • 字符编码问题:不同字符编码之间的转换可能导致数据丢失或乱码。

6.2 优化建议

  • 使用高效的数据结构:如使用动态数组或哈希表来提高字符串操作的效率。
  • 采用先进的匹配算法:在模式匹配中,选择合适的算法以提高匹配速度,如KMP或BM算法。
  • 优化内存使用:尽量减少不必要的字符串拷贝,使用原地修改或引用传递来节省内存。

7. 总结

串是计算机科学中的基础数据结构之一,广泛应用于文本处理、数据存储和传输等场景。通过深入理解串的定义、存储结构、基本操作和模式匹配算法,开发者可以更加高效地处理各种字符串相关的任务。掌握串的优化技巧和高级算法,有助于在实际应用中应对复杂的串处理问题,提高程序的性能和稳定性。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hive3:常用的内置函数

1、查看函数列表 -- 查看所有可用函数 show functions; -- 查看count函数使用方式 describe function extended count;2、数学函数 -- round 取整&#xff0c;设置小数精度 select round(3.1415926); -- 取整(四舍五入) select round(3.1415926, 4); -- 设置小数精度4位(四…

应急响应-DDOS-典型案例

某单位遭受DDoS攻击事件如下 事件背景 2019年2月17日&#xff0c;某机构门户网站无法访问&#xff0c;网络运维人员称疑似遭受DDoS攻击&#xff0c;请求应急响应工程师协助。 事件处置 应急响应工程师在达到现场后&#xff0c;通过查看流量设备&#xff0c;发现攻击者使用僵…

汇编语言:call、call far ptr、call word ptr、call dword ptr、call 寄存器

引言 call指令是转移指令&#xff0c;CPU执行call指令&#xff0c;进行两步操作&#xff1a; &#xff08;1&#xff09;将当前IP或当前CS和IP压入栈中 &#xff08;2&#xff09;转移。call指令不能短转移&#xff0c;除此之外&#xff0c;call指令转移的方法跟jmp指令的原理…

Java流程控制09:练习题:打印三角形

本节视频链接&#xff1a;https://www.bilibili.com/video/BV12J41137hu?p44&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5https://www.bilibili.com/video/BV12J41137hu?p44&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 通过嵌套for循环可以实现打印三角形&#xff…

使用C#禁止Windows系统插入U盘(除鼠标键盘以外的USB设备)

试用网上成品的禁用U盘的相关软件&#xff0c;发现使用固态硬盘改装的U盘以及手机等设备&#xff0c;无法被禁止&#xff0c;无奈下&#xff0c;自己使用C#手搓了一个。 基本逻辑&#xff1a; 开机自启&#xff1b;启动时&#xff0c;修改注册表&#xff0c;禁止系统插入USB存…

银河麒麟服务器操作系统Kylin-Server-V10-SP3-2403-Release-20240426-x86_64安装步骤

银河麒麟服务器操作系统 Kylin-Server-V10-SP3-2403-Release-20240426-x86_64安装步骤 一、准备工作1. 下载ISO镜像2. 制作安装介质3. 设置BIOS 二、安装过程1. 启动系统2. 选择安装语言3. 选择安装配置4. 配置root密码与创建用户5. 开始安装6. 重启系统7. 同意许可协议 三、系…

通义千问( 四 ) Function Call 函数调用

4.2.function call 函数调用 大模型在面对实时性问题、私域知识型问题或数学计算等问题时可能效果不佳。 您可以使用function call功能&#xff0c;通过调用外部工具来提升模型的输出效果。您可以在调用大模型时&#xff0c;通过tools参数传入工具的名称、描述、入参等信息。…

C语言(16)——初识单链表

1.链表的概念及结构 概念&#xff1a;链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 结构图&#xff1a; 补充说明&#xff1a; 1、链式机构在逻辑上是连续的&#xff0c;在物理结构上不⼀定连续 2、…

Oracle Java JDK 21 下载地址及安装教程

Oracle JDK 21 官方地址 https://www.oracle.com/java/technologies/downloads/#java21 1. Linux 版本 ARM64 Compressed Archive https://download.oracle.com/java/21/latest/jdk-21_linux-aarch64_bin.tar.gz ARM64 RPM Package https://download.oracle.com/java/21/late…

Python爬虫图片:从入门到精通

在数字化时代&#xff0c;图片作为信息传递的重要媒介之一&#xff0c;其获取和处理变得越来越重要。Python作为一种功能强大且易于学习的编程语言&#xff0c;非常适合用来编写爬虫程序&#xff0c;帮助我们自动化地从互联网上获取图片资源。本文将从基础到高级&#xff0c;详…

【qt】跳转到另一个界面

如何在一个界面跳转到另一个界面呢&#xff1f; 1.具体步骤 1.先新建一个界面 2.选择qt设计师界面 3.选择W 4.新界面名称 5.界面设计 因为我们要实现通信&#xff0c;需要一个发送信息栏&#xff0c;一个发送按钮&#xff0c;一个清空发送栏按钮 6.实现跳转 我们可以参…

python 已知x+y=8 求x*y*(x-y)的最大值

先用导数求解 已知xy8 求xy(x-y)的最大值 令y8-x 则 f(x)x⋅(8−x)⋅(x−(8−x))x⋅(8−x)⋅(2x−8) 导数方程为 f(x)-3x^2 24x - 32 求方程 − 3 x 2 24 x − 32 0 -3x^2 24x - 32 0 −3x224x−320 的根。 首先&#xff0c;我们可以尝试对方程进行因式分解。观察…

Airtest 的使用

Airtest 介绍 Airtest Project 是网易游戏推出的一款自动化测试框架&#xff0c;其项目由以下几个部分构成 Airtest : 一个跨平台的&#xff0c;基于图像识别的 UI 自动化测试框架&#xff0c;适用于游戏和 App &#xff0c; 支持 Windows, Android 和 iOS 平台&#xff0c…

鸿蒙应用程序框架基础

鸿蒙应用程序框架基础 应用程序包基础知识应用的多Module设计机制Module类型 Stage模型应用程序包结构开发态包结构编译包形态发布台包结构选择合适的包类型 应用程序包基础知识 应用的多Module设计机制 **支持模块化开发&#xff1a;**一个应用通常会包含多种功能&#xff0…

为什么MCU I2C波形中会出现的脉冲毛刺?

在I2C的波形中&#xff0c;经常会发现有这样的脉冲毛刺&#xff0c;会被认为是干扰或者器件不正常。 看到这个波形时&#xff0c;可以先数一下出现在第几个clock的位置&#xff0c;如果出现在第9个clock的低电平期间&#xff0c;就不是干扰或者器件异常导致。 在I2C的协议中&a…

虎牙驶入快车道

撰稿 | 多客 来源 | 贝多财经 一份Q2财报&#xff0c;狠狠打脸了那些唱反调的人&#xff0c;特别是故意唱衰直播和游戏公司的一些TMT观察者。 同时&#xff0c;直播平台如何健康转型实现可持续发展&#xff0c;游戏相关服务业务应该怎么做增量&#xff0c;虎牙的这份财报也给…

【Kubernetes】虚拟 IP 与 Service 的代理模式

虚拟 IP 与 Service 的代理模式 1.userspace 代理模式2.iptables 代理模式3.IPVS 代理模式 由于 Service 的默认发布类型是 ClusterlP&#xff0c;因此也可以把 ClusterIP 地址叫作 虚拟 IP 地址。在 Kubernetes 创建 Service 时&#xff0c;每个节点上运行的 kube-proxy 会自动…

golang基于WMI获取所有外接硬盘(USB,移动硬盘)信息

golang基于WMI获取所有外接硬盘(USB,移动硬盘)信息 package mainimport ("fmt""regexp""github.com/StackExchange/wmi""github.com/shirou/gopsutil/v3/disk" )// 定义 WMI 类结构体 type Win32_LogicalDiskToPartition struct {Ant…

高数4.2 积分方法-换元积分法

1. 第一类换元积分法 2. 第二类换元积分法

算法【Java】 —— 滑动窗口

滑动窗口 在上一篇文章中&#xff0c;我们了解到了双指针算法&#xff0c;在双指针算法中我们知道了前后指针法&#xff0c;这篇文章就要提到前后指针法的一个经典的使用 —— 滑动窗口&#xff0c;在前后指针法中&#xff0c;我们知道一个指针在前&#xff0c;一个指针在后&a…