1. 字符串定义

字符串 string 是由 n 个字符组成的一个有序整体 n >= 0。例如,s = "BEIJING"s 代表这个串的串名,BEIJING 是串的值。这里的双引号不是串的值,作用只是为了将串和其他结构区分开。

在实际操作中,我们经常会用到一些特殊的字符串:​

  • 空串,指含有零个字符的串。例如,s = "",书面中也可以直接用 Ø 表示。

  • 空格串,只包含空格的串。它和空串是不一样的,空格串中是有内容的,只不过包含的是空格,且空格串中可以包含多个空格。例如,s = " ",就是包含了 3 个空格的字符串。

  • 子串,串中任意连续字符组成的字符串叫作该串的子串。

  • 原串通常也称为主串。例如:a = "BEI"b = "BEIJING"c = "BJINGEI"

  1. 对于字符串 ab 来说,由于 b 中含有字符串 a ,所以可以称 ab 的子串,ba 的主串;
  2. 而对于 ca 而言,虽然 c 中也含有 a 的全部字符,但不是连续的 BEI ,所以串 ca 没有任何关系。

2. 字符串基本操作

字符串和线性表的操作很相似,但由于字符串针对的是字符集,所有元素都是字符,因此字符串的基本操作与线性表有很大差别。线性表更关注的是单个元素的操作,比如增删查一个元素,而字符串中更多关注的是查找子串的位置、替换等操作。

2.1 新增字符串

字符串的新增操作和数组非常相似,都牵涉对插入字符串之后字符的挪移操作,所以时间复杂度是 O(n)

2.2 删除字符串

字符串的删除操作和数组同样非常相似,也可能会牵涉删除字符串后字符的挪移操作,所以时间复杂度是 O(n)

2.3 查找字符串

字符串的查找操作,是一个高频问题。

例如,字符串 s = "goodgoogle",判断字符串 t = "google"s 中是否存在。需要注意的是,如果字符串 t 的每个字符都在 s 中出现过,这并不能证明字符串 ts 中出现了。例如当 t = "dog" 时,那么字符 dog 都在 s 中出现过,但他们并不连在一起。

2.3.1 查找子串

首先,我们来定义两个概念,主串和模式串。我们在字符串 A 中查找字符串 B,则 A 就是主串,B 就是模式串。我们把主串的长度记为 n,模式串长度记为 m。由于是在主串中查找模式串,因此,主串的长度肯定比模式串长,n>m。因此,字符串匹配算法的时间复杂度就是 nm 的函数。

假设要从主串 s = "goodgoogle" 中找到 t = "google" 子串。根据我们的思考逻辑,则有:

  • 首先,我们从主串 s 第 1 位开始,判断 s 的第 1 个字符是否与 t 的第 1 个字符相等;
  • 如果不相等,则继续判断主串的第 2 个字符是否与 t的第 1 个字符相等。直到在 s 中找到与 t 第一个字符相等的字符时,然后开始判断它之后的字符是否仍然与 t 的后续字符相等;
  • 如果持续相等直到 t 的最后一个字符,则匹配成功;
  • 如果发现一个不等的字符,则重新回到前面的步骤中,查找 s 中是否有字符与 t的第一个字符相等;
  • 如下图所示,s 的第 1 个字符和 t 的第 1 个字符相等,则开始匹配后续。直到发现前三个字母都匹配成功,但 s 的第 4 个字母匹配失败,则回到主串继续寻找和 t 的第一个字符相等的字符;
  • 如下图所示,这时我们发现主串 s 第 5 位开始相等,并且随后的 6 个字母全匹配成功,则找到结果。

这种匹配算法需要从主串中找到跟模式串的第 1 个字符相等的位置,然后再去匹配后续字符是否与模式串相等。显然,从实现的角度来看,需要两层的循环。第一层循环,去查找第一个字符相等的位置,第二层循环基于此去匹配后续字符是否相等。因此,这种匹配算法的时间复杂度为 O(nm)。其代码如下:

是否包含子串的代码,其中 a 为主串, b 为子串。

#include <iostream>
#include <string>int main()
{std::string a;std::string b;getline(std::cin, a);getline(std::cin, b);int is_find = 0;for(int i=0; i<a.length(); i++){if(a[i] == b[0]){int sub_str_length = 0;for(int j=0; j<b.length(); j++){if(a[i+j] != b[j]){break;}sub_str_length = j;}if(sub_str_length == b.length() -1){is_find = 1;}}}std::cout << is_find << std::endl;
}

2.3.2 公共子串计算

假设有且仅有 1 个最大公共子串。比如,输入 a = "13452439"b = "123456"。由于字符串 "345" 同时在 ab 中出现,且是同时出现在 ab 中的最长子串。因此输出 "345"

对于这个问题有两种解决思路:

  1. 使用动态规划来解决;
  2. 使用前面介绍的匹配算法;

在这里我们沿用前面的匹配算法。

假设字符串 a 的长度为 n,字符串 b 的长度为 m,可见时间复杂度是 nm 的函数。

  • 首先,你需要对于字符串 ab 找到第一个共同出现的字符,这跟前面讲到的匹配算法在主串中查找第一个模式串字符一样;
  • 然后,一旦找到了第一个匹配的字符之后,就可以同时在 ab 中继续匹配它后续的字符是否相等。这样 ab 中每个互相匹配的字串都会被访问一遍。全局还要维护一个最长子串及其长度的变量,就可以完成了。

从代码结构来看,第一步需要两层的循环去查找共同出现的字符,这就是 O(nm)。一旦找到了共同出现的字符之后,还需要再继续查找共同出现的字符串,这也就是又嵌套了一层循环。可见最终的时间复杂度是 O(nmm),即 O(nm²)。代码如下:

#include <iostream>
#include <string>int main()
{std::string a;std::string b;getline(std::cin, a);getline(std::cin, b);int max_len = 0;std::string sub_str = "";for(int i=0; i<a.length(); i++){for(int j=0; j<b.length(); j++){if(a[i] == b[j]){for(int m=i, n=j; m<a.length(), n<b.length(); m++, n++){if(a[m] != b[n]){break;}if((m - i + 1) > max_len){max_len = m - i + 1;sub_str = a.substr(i, m+1);}}}}}std::cout << max_len << std::endl;std::cout << sub_str << std::endl;
}

算法基础(09)— 字符串常用操作相关推荐

  1. JavaScript之基础-9 JavaScript String(内置对象、String概述、字符串常用操作、模式匹配)...

    一.JavaScript 内置对象 内置对象 - 什么是内置对象? 内置对象就是ECMAScript标准中已经定义好的,由浏览器厂商已经实现的标准对象 - 内置对象中封装了专门的数据和操作数据常用的A ...

  2. python对输入的字符串进行解析_python数据类型_字符串常用操作(详解)

    这次主要介绍字符串常用操作方法及例子 1.python字符串 在python中声明一个字符串,通常有三种方法:在它的两边加上单引号.双引号或者三引号,如下: name = 'hello' name1 ...

  3. python基础实例-Python基础之字符串常见操作经典实例详解

    本文实例讲述了Python基础之字符串常见操作.分享给大家供大家参考,具体如下: 字符串基本操作 切片 # str[beg:end] # (下标从 0 开始)从下标为beg开始算起,切取到下标为 en ...

  4. python加密字符串小写字母循环后错两位_python数据类型_字符串常用操作(详解)

    这次主要介绍字符串常用操作方法及例子 1.python字符串 在python中声明一个字符串,通常有三种方法:在它的两边加上单引号.双引号或者三引号,如下: name = 'hello' name1 ...

  5. java 字符查找 截断_java字符串常用操作(查找、截取、分割)

    public class 字符串常用操作 { public static void main(String[] args) { /* * 查找子串 */ String str1="dwqae ...

  6. python基础(字符串常用、数字类型转换、基本运算符与流程控制)

    一.字符串常用操作: #! /usr/bin/env python # -*- coding: utf-8 -*- # __author__ = "Z'N'Y" # Date: 2 ...

  7. 字符串常用操作函数一

    字符串常用操作函数一 字符串常用操作函数一 1.gets(); 1.1用法 2.puts(); 2.1用法: 2.2 printf.putchar和puts函数的区别: 3.memset(); 3.1 ...

  8. php字符串相关操作,PHP字符串常用操作

    常用操作有: PHP中有两个内建的函数:count() 和sizeof(),可以实现得到数组的长度 count($sttr);数组长度 字符串长度:strlen(string $a); 判断是否相同, ...

  9. 真香!精心整理了 100+Python 字符串常用操作

    来源丨萝卜大杂烩 作者丨周萝卜 字符串作为平时使用最多的数据类型,其常用的操作我们还是很有必要熟记于心的,本文整理了多种字符串的操作的案例,还是非常用心,记得点赞收藏~ 字符串切片操作 test = ...

  10. 精心整理了100+Python字符串常用操作,备用

    字符串作为平时使用最多的数据类型,其常用的操作我们还是很有必要熟记于心的,本文整理了多种字符串的操作的案例,还是非常用心,记得点赞收藏哦 文章很长,高低要忍一下,如果忍不了,那就收藏吧,总会用到的 萝 ...

最新文章

  1. Eclipse插件:Eclipse Color Theme
  2. AndroidManifest详解
  3. RSA公私钥加解密方式-工具类
  4. 使用tSQLt创建SQL单元测试实用程序过程
  5. mysql数据传出_从MySQL读取数据,以List方式传出
  6. UVa 10118 免费糖果(记忆化搜索+哈希)
  7. 本地开发phpmyadmin去登陆验证
  8. html当前时间插件,HTML日期时间插件
  9. Flash遮罩之溜光字制作二
  10. 计算机病毒分为哪三类
  11. 人工智能资料库:第37辑(20170220)
  12. ts封装,H264和aac 封装成为ts,并生成m3u8
  13. HIT CSAPP大作业--程序人生
  14. 自定义微信小程序顶部导航栏(自适应微信胶囊按钮,flex布局)
  15. 肖明计算机网络答案,袭肖明
  16. 数据库事务 ACID
  17. IOS之plist文件
  18. Ktor: Kotlin Web后端框架 快速开始入门
  19. android实现地图api公交线路查询,android实现查询公交车还有几站的功能
  20. 软考系统分析师-湖南省历年通过人数

热门文章

  1. docker停止、删除容器、删除镜像 一看就理解
  2. 2022-2028年中国橡胶板的制造行业发展战略规划及投资方向研究报告
  3. 2022-2028年中国防水橡胶布行业市场发展模式及投资前景分析报告
  4. 改变自己,让自己变得更好
  5. 人要懂得放下已经发生,却又无法改变的事情
  6. 汇编语言中寻址方式[bx + idata]
  7. LeetCode简单题之判断矩阵经轮转后是否一致
  8. LeetCode简单题之旋转字符串
  9. 传感器标定两篇顶会论文解析
  10. Git基本命令和GitFlow工作流