数据结构 - 字符串

2,825 阅读13分钟

Create by jsliang on 2019-8-22 07:41:30
Recently revised in 2019-09-16 19:39:15

数组 - 最简单的内存数据结构。

字符串 - 随时可以转换成数字或者数组的简单类型。

重点推荐:String - MDN

jsliang 的联系方式尽在 jsliang 的文档库github.com/LiangJunron…

一 目录

不折腾的前端,和咸鱼有什么区别

目录
一 目录
二 前言
三 字符串的存储结构
四 字符串的常用知识点
4.1 字符串 - 查询
4.2 字符串 - 正则表达式
4.3 字符串 - 修改
4.4 字符串 - 转类型
4.5 字符串 - 大小写
4.6 字符串 - 去空格
五 LeetCode - 字符串训练
六 总结

二 前言

返回目录

什么是字符串?

字符串是有零个或者多个字符组成的有序数列。

如果字符串的个数为零,则表明这个字符串为 空串(Null String),长度为 0。空串表示为:''

如果字符串由空格组成,那么它就不是空串,而是有 n 个空格长度的字符串,例如:' '(它包含了一个空格,所以长度为 1)。

空串和 n 个空格组成的字符串

const nullString = '';
const spaceString = ' ';
console.log(nullString.length); // 0
console.log(spaceString.length); // 1

为什么要引入这个概念呢?

因为在一些场景,你需要知道这个字符串是否为空,从而做某些判断。

例如:

在这题中,就需要判断它是否为空串,如果为空串则返回 0:

var strStr = function(haystack, needle) {
  if (!needle.length && !haystack.length) {
    return 0;
  }
  if (!needle.length) {
    return 0;
  }
  // ... 代码省略
};

同时,通过这题,我们还可以引入 子串 的概念:

给定一个 haystack 字符串和一个 needle 字符串,
在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从 0 开始)。
如果不存在,则返回 -1。

示例:

输入: haystack = "hello", needle = "ll"
输出: 2

在这里,hello 就是 ll 的主串,llhello 的子串。

如果你初中数学还不赖,那么你大概可以将 ll 当做是 hello 的子集。

到这里,我们开始了解到字符串的一些点,如果你觉得还可以接受,请继续往下看。

三 字符串的存储结构

返回目录

字符串分为两种存储结构:顺序存储和链式存储。

  • 顺序存储:用一组地址连续的存储单元来存储字符串中的字符序列,我们一般用数组来定义。
  • 链式存储:字符串的链式存储,和线性表的链式存储很相似。但是由于字符串结构的特殊性,结构中的每个元素为字符。如果也按照线性表的链式存储,每个节点存放一个字符,那么就会造成很大的空间浪费。

那么问题来了:听不懂是不是。

不管你听不听得懂,反正 jsliang 是不太懂了。

所以咱不管它有的没的先,看完一遍就行了。

是的,不用你以为,要我以为,这篇文章中听我的就好了。/滑稽

在这里引入这个,主要是表明,在很多场合,我们会将 字符串转换成数组

'jsliang'.split(''); // ['j','s','l','i','a','n','g']

从而使用数组中的丰富 API:

注释 1:不强行理解 顺序存储和链式存储 的概念是因为 jsliang 觉得现在还没有到需要理解的地步。

注释 2:如果你纯粹是个知识大师,却敲不了一行代码,那是不行的,所以 jsliang 强烈推荐在了解概念的同时多练习练习。

四 字符串的常用知识点

返回目录

在上面我们讲解了字符串的基础知识,并且提到了字符串在使用中会转换成数字或者数组,从而更方便我们进行编程。

那么,下面我们就通过字符串相关的 LeetCode 题,来串联一些字符串的 API,从而帮助小伙伴们快速了解其使用方式,加强自己的基础。

应用程序接口(API)是基于编程语言构建的结构,使开发人员更容易地创建复杂的功能。它们抽象了复杂的代码,并提供一些简单的接口规则直接使用。

客户端 JavaScript 中有很多可用的 API:
浏览器 API 内置于Web浏览器中,能从浏览器和电脑周边环境中提取数据,并用来做有用的复杂的事情。
第三方 API 缺省情况下不会内置于浏览器中,通常必须在Web中的某个地方获取代码和信息。

在此之前,我们先看看字符串有哪些 API,然后开始针对一些常见的 API,在 LeetCode 中锻炼一下思路:

浏览器内置对象只字符串 API

new String; // 在浏览器敲入 new String

// 输出
String {
  length: 0,
  __proto__: {
    anchor: ƒ anchor(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    big: ƒ big(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    blink: ƒ blink(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    bold: ƒ bold(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    charAt: ƒ charAt(),
    charCodeAt: ƒ charCodeAt(),
    codePointAt: ƒ codePointAt(), // 返回使用 UTF-16 编码的给定位置的值的非负整数。
    concat: ƒ concat(),
    constructor: ƒ String(), // 用于创造对象的原型对象的特定的函数。
    endsWith: ƒ endsWith(), // 需要兼容处理(ES6)
    fixed: ƒ fixed(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    fontcolor: ƒ fontcolor(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    fontsize: ƒ fontsize(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    includes: ƒ includes(),
    indexOf: ƒ indexOf(),
    italics: ƒ italics(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    lastIndexOf: ƒ lastIndexOf(),
    length: 0,
    link: ƒ link(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    localeCompare: ƒ localeCompare(), // 返回一个数字表示是否引用字符串在排序中位于比较字符串的前面,后面,或者二者相同。
    match: ƒ match(),
    matchAll: ƒ matchAll(),
    normalize: ƒ normalize(), // 返回调用字符串值的Unicode标准化形式。
    padEnd: ƒ padEnd(),
    padStart: ƒ padStart(),
    repeat: ƒ repeat(),
    replace: ƒ replace(),
    search: ƒ search(),
    slice: ƒ slice(),
    small: ƒ small(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    split: ƒ split(),
    startsWith: ƒ startsWith(), // 需要兼容处理(ES6)
    strike: ƒ strike(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    sub: ƒ sub(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    substr: ƒ substr(), // 避免使用,后期可能被移除
    substring: ƒ substring(),
    sup: ƒ sup(), // 被限制使用,因为只对可用的 HTML 标签和属性提供部分支持。
    toLocaleLowerCase: ƒ toLocaleLowerCase(),
    toLocaleUpperCase: ƒ toLocaleUpperCase(),
    toLowerCase: ƒ toLowerCase(),
    toString: ƒ toString(),
    toUpperCase: ƒ toUpperCase(),
    trim: ƒ trim(),
    trimEnd: ƒ trimEnd(),
    trimLeft: ƒ trimStart(),
    trimRight: ƒ trimEnd(),
    trimStart: ƒ trimStart(),
    valueOf: ƒ valueOf(), // 返回特定对象的原始值。
    Symbol(Symbol.iterator): ƒ [Symbol.iterator](),
  }
}

常用字符串 API

API 功能
str.charAt(index) 返回特定位置的字符。
str.charCodeAt(index) 返回表示给定索引的字符的 Unicode 的值。
str.concat() 连接两个字符串文本,并返回一个新的字符串。
str.includes() 判断一个字符串里是否包含其他字符串。
str.indexOf() 从字符串对象中返回首个被发现的给定值的索引值,如果没有找到则返回 -1。
str.lastIndexOf() 从字符串对象中返回最后一个被发现的给定值的索引值,如果没有找到则返回 -1。
str.length 返回了字符串的长度。
str.match() 使用正则表达式与字符串相比较。
str.matchAll() 返回一个包含所有匹配正则表达式及分组捕获结果的迭代器。
str.padEnd() 在当前字符串尾部填充指定的字符串,直到达到指定的长度。返回一个新的字符串。
str.padStart() 在当前字符串头部填充指定的字符串,直到达到指定的长度。返回一个新的字符串。
str.repeat() 返回指定重复次数的由元素组成的字符串对象。
str.replace() 被用来在正则表达式和字符串直接比较,然后用新的子串来替换被匹配的子串。
str.search() 对正则表达式和指定字符串进行匹配搜索,返回第一个出现的匹配项的下标。
str.slice() 摘取一个字符串区域,返回一个新的字符串。
str.split() 通过分离字符串成子串,将字符串对象分割成字符串数组。
str.substring() 返回在字符串中指定两个下标之间的字符。
str.toLocaleLowerCase() 根据当前区域设置,将符串中的字符转换成小写。对于大多数语言来说,toLowerCase 的返回值是一致的。
str.toLocaleUpperCase() 根据当前区域设置,将字符串中的字符转换成大写,对于大多数语言来说,toUpperCase的返回值是一致的。
str.toLowerCase() 将字符串转换成小写并返回。
str.toUpperCase() 将字符串转换成大写并返回。
type.toString() 返回用字符串表示的特定对象。
str.trim() 从字符串的开始和结尾去除空格。
str.trimEnd() / str.trimRight() 从字符串的右侧去除空格。
str.trimStart() / str.trimLeft() 从字符串的左侧去除空格。

如上,我们列出了 23 种 可能 比较常用的 字符串 API

但是,如果仅仅这样列出来,那还不如直接看 MDN 关于 JavaScript 字符串的讲解:

所以,下面将进行归类,并通过 LeetCode 进行详细剖析学习。

参考文献

4.1 字符串 - 查询

返回目录

  1. str.length:返回了字符串的长度。详细学习
  2. str.charAt(index):返回特定位置的字符。详细学习
  3. str.charCodeAt(index):返回表示给定索引的字符的 Unicode 的值。详细学习
  4. str.includes(searchString, fromIndex)):判断一个字符串里是否包含其他字符串。详细学习
  5. str.indexOf(searchString, fromIndex):从字符串对象中返回首个被发现的给定值的索引值,如果没有找到则返回 -1。详细学习
  6. str.lastIndexOf(searchString, fromIndex):从字符串对象中返回最后一个被发现的给定值的索引值,如果没有找到则返回 -1。详细学习
  7. str.substring(indexStart, indexEnd):返回在字符串中指定两个下标之间的字符。详细学习

4.2 字符串 - 正则表达式

返回目录

  1. str.match(regexp):使用正则表达式与字符串相比较。详细学习
  2. str.matchAll(regexp):返回一个包含所有匹配正则表达式及分组捕获结果的迭代器。详细学习
  3. str.replace(regexp |substr, newSubStr| function):被用来在正则表达式和字符串直接比较,然后用新的子串来替换被匹配的子串。详细学习
  4. str.search(regexp):对正则表达式和指定字符串进行匹配搜索,返回第一个出现的匹配项的下标。详细学习

4.3 字符串 - 修改

返回目录

  1. str.concat(string2, string3, ..., stringN):连接两个字符串文本,并返回一个新的字符串。详细学习
  2. str.padStart(targetLength, padString):在当前字符串头部填充指定的字符串,直到达到指定的长度。返回一个新的字符串。详细学习
  3. str.padEnd(targetLength, padString):在当前字符串尾部填充指定的字符串,直到达到指定的长度。返回一个新的字符串。详细学习
  4. str.repeat(count):返回指定重复次数的由元素组成的字符串对象。详细学习
  5. str.slice(beginIndex, endIndex):摘取一个字符串区域,返回一个新的字符串。详细学习

4.4 字符串 - 转类型

返回目录

  1. str.split(separator, limit):(字符串转数组)通过分离字符串成子串,将字符串对象分割成字符串数组。详细学习
  2. type.toString():(其他类型转字符串)返回用字符串表示的特定对象。详细学习

4.5 字符串 - 大小写

返回目录

  1. str.toLocaleLowerCase() / str.toLowerCase():根据当前区域设置,将符串中的字符转换成小写。对于大多数语言来说,toLowerCase 的返回值是一致的。详细学习
  2. str.toLocaleUpperCase() / str.toUpperCase():根据当前区域设置,将字符串中的字符转换成大写,对于大多数语言来说,toUpperCase 的返回值是一致的。详细学习

4.6 字符串 - 去空格

返回目录

  1. str.trim():从字符串的开始和结尾去除空格。详细学习
  2. str.trimStart() / str.trimLeft():从字符串的左侧去除空格。详细学习
  3. str.trimEnd() / str.trimRight():从字符串的右侧去除空格。详细学习

五 LeetCode - 字符串训练

返回目录

首先,由于 jsliang 在编写时发现,如果针对某个 API 然后找到对应的某个题给小伙伴尝试,无异议饮鸩止渴,对后期成长是没有帮助的。

然后jsliang 尝试攻略的这些题目的覆盖范围可能不是小伙伴想要的(即做了对字符串没法非常深入了解,覆盖面也可能不全),所以小伙伴可以尝试自己选题:

最后,贴上一些目前 jsliang 已经攻略的字符串题目,希望对小伙伴们有所帮助:

六 总结

返回目录

经过前面一系列的折腾,我们基本对字符串的各种操作有所了解,虽然谈不上 精通,但是支持日常工作是毫无问题的。

毕竟在日常工作中,字符串很常见,所以我们还是需要去发掘它,使用它的。

那么,字符串的讲解就到此为止啦,咱们下个知识点再见~

如果你觉得 jsliang 写得很 OK,欢迎点赞、留言、加微信好友、关注微信公众号等。

咱们,将继续探索,扎实编程基础,了解更多的数据结构和算法!

jsliang 的联系方式尽在 jsliang 的文档库github.com/LiangJunron…


不折腾的前端,和咸鱼有什么区别!

jsliang 会每天更新一道 LeetCode 题解,从而帮助小伙伴们夯实原生 JS 基础,了解与学习算法与数据结构。

扫描上方二维码,关注 jsliang 的公众号,让我们一起折腾!

知识共享许可协议
jsliang 的文档库梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/LiangJunron…上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。