数据结构与算法 | 第四章:字符串
本文参考网课为 数据结构与算法 1 第四章字符串,主讲人 张铭 、王腾蛟 、赵海燕 、宋国杰 、邹磊 、黄群。
本文使用IDE为 Clion,开发环境 C++14。
更新:2023 / 11 / 12
数据结构与算法 | 第四章:字符串
- 字符串
- 概念
- 字符串
- 字符
- 字符编码
- 子串
- 抽象数据类型
- 存储与实现
- 顺序存储
- C / C++的标准字符串
- 标准串运算
- 字符串长度
- 字符串寻找字符
- C++的字符串类 String
- 字符串类运算
- 构造算子
- 赋值算子
- 提取子串
- 模式匹配
- 概念
- 应用
- 分类
- 精确匹配
- 单选模式
- 朴素匹配算法
- KMP 算法
- 近似匹配
- 参考链接
字符串
概念
字符串
字符串 是一类简单的由 字符( char)构成的线性结构的 线性表。
字符串 简称 串,为零个或多个 字符 / 符号 构成的有限序列。
n (>=0) 个 字符 的有限序列,一般记作 S C0C1…Cn-1。
S为串名- C0C1…Cn-1为串值。Ci中i位置上的
字符/符号 n为字符串长度。长度为零的串,不包含任何字符内容。理论上,一个字符串的长度可以为任意的有限长度,实际上:- 定长
具有固定的最大长度,所用内存量始终如一 - 变长
根据实际需要伸缩,以提高内存空间利用率
- 定长
字符
字符 的取值依赖于字符集。常用的字符集包括:
- 由 {0, 1} 所构成的二进制字符集
- 由4个字符组成的生物信息的DNA字符集
- 由26个字符和标点符号等组成的英语语言
- 由6763个常用汉字和682个全角非汉字符号等所构成的简体中文标准字符集GB2312
- 适用于跨语言、跨平台的通用字符集USC(
Universal Character Set)
这些 字符 在计算机里是如何存储和运算呢?这就需要 字符编码 来建立 字符集 与计算机数字系统之间的对应关系。
字符编码
字符编码 会将 字符集 里的每一个字符编码为由0和1组成的序列。那么,具体,哪一个二进制序列表示哪一个符号则取决于我们所使用的编码方式。常用的编码方式有:
ASCII 编码- 使用单字节(
8 bits)对字符集charset的128个符号进行编码 - 基于拉丁字母的编码,主要用于现代英语和多种西欧语言,也为大多数程序设计语言所采用,例如C和C++
- 使用单字节(
- 其他编码方式
ANSI 编码
支持多种东方语言:GB2312、BIG5、JIS等。不同国家/地区制定不同的标准,不同ANSI编码间互不兼容Unicode(跨语言跨平台)
各种语言中的每一个字符具有唯一的数字编号,便于跨平台的文本转换
无论采用哪一种编码方式,对于一个给定字符集中的字符编码需要满足一组无歧义的规则,使得字符集中的每一个字符都对应唯一的一个编码。且不同的字符编码之间要满足偏序关系。
所谓偏序关系,是定义在集合上的一个二元关系满足自反性、反对称性和传递性。在偏序规则下,
- 连续的数字
0-9是要连续编码的。像在ASCII 编码下,0的编码是48,那么1的编码就是49。 - 连续的字符也是需要连续编码的。像在
ASCII 编码下,大写字母A的编码是65,那么B的编码就是66。
通常在字符偏序下,根据字符的自然含义,两个字符之间是可以根据它的编码值进行直接的比较的。两个字符串就会按照构成的字符之间的编码进行大小的比较来得到字典序。
子串
一个 字符串 中任意个连续的字符组成的子序列称为该串的 子串 。
比如说一个长度为 n 的字符串 s1 和长度为 m 的 s2,0<=m<=n。若存在整数 j (0<=i<=n-m) 使得 bj = ai+j,j = 0,1,…,m-1同时成立,则称串 s2 是串 s1 的字串,或称 s1 包含串 s2。
另外,空串是任意串的子串。任意串S都是其自身的子串。
子串 相关的应用有:提取、插入、寻找、删除等等。
抽象数据类型
int length(); // 返回串的长度
int isEmpty(); // 判断串是否为空串
int find(const char c, const int s); // 从s开始搜索串寻找一个给定字符
int strcmp(const char *s1, const char *s2); // 串比较void clear(); // 清空串string substr(const int s, const int len); // 从s开始提取一个长度为len的子串
string insert(const char s, const int index); // 往串中给定位置插入一个字符
string append(const char c); // 往串尾添加字符
string concatenate(const char *s); // 往本串后面链接串schar *strcpy(char *s1, const char *s2); // 串复制
存储与实现
字符串 是一种基本元素为 字符 的特殊线性表,所以本质上它的存储也有线性表的顺序和链式两种方式。但是对于 字符串 这类特殊的线性表来说,链式存储的结构性开销过大而很少被采用,所以我们主要以顺序存储为主来介绍 字符串 的存储与实现。
顺序存储
对于定长的 字符串 采用顺序存储方式,即事先申请固定长度的空间但需要有相应的机制来确切的知道当前串的长度。所以一般有3种处理方案:
- 用
字符串的第一个元素S[0]作为记录串长的存储单元
缺点:该方式决定串的最大长度不能超过256 2。 - 另辟空间存储串的长度
缺点:串的最大长度一般是静态给定的,而非动态申请 - 特殊标记串的结束
C / C++ 的标准字符串( #include <string.h> )
C / C++的标准字符串
C / C++ 的标准字符串是将字符串变量定义为字符数组 char s[M]。
字符串的结束标记是 ASII码中8位全0码 ‘\0’,亦称 NULL。因此,字符串的实际长度为 M-1。
例如,chars s1[6]='value';,定义了一个名为 chars 的字符数组,长度为6位,但是只能存储5位字母。
需要注意的是,标准串定义成了数组,所以它是无法作为左值被赋值的。例如,s1 = s2 是不合规的。
标准串运算
函数库 <string.h> 提供字符串处理函数来方便字符串的运算。下面是 string.h 提供的一些常用的字符串的操作:
| 函数 | 作用 |
|---|---|
int strlen(char *s) | 串长 |
char *strcpy(char *s1, char*s2); | 串复制 |
char *strcat(char *s1, char *s2); | 串拼接 |
int strcmp(char *s1, char *s2); | 串比较 |
char *strchr(char *s, char c); | 字符定位 |
char *strrchr(char *s, char c); | 字符定位 |
int *strstr(char* s2, char* s1) | 子串抓取 |
字符串长度
- 1. 求字符串的长度
int strlen(char s[])
{int i = 0;while (s[i] != 0)i ++;return i;
}
- 2. 比较2个字符串的长度
int strcmp(const char *s1, const char *s2) // 定义2个字符串,分别为s1、s2
{int i = 0;while (s2[i] != '\0' && s1[i] != '\0'){ // 字符串的结束标记为 \0if (s1[i] > s2[i])return 1; // s1比s2长else if (s1[i] < s2[i])return -1; // s1比s2短i ++;}if (s1[i] == '\0' && s2[i] != '\0')return -1; // s1比s2短else if (s2[i] == '\0' && s1[i] != '\0')return 1; // s2比s1短return 0;
}
或者,
int strcmp_1(char *s1, char *s2) // 定义2个字符串,分别为s1、s2
{int i;for (i=0; s1[i] == s2[i]; ++i){if (s1[i] == '\0' && s2[i] == '\0')return 0; // 两个字符串相等}return (s1[i]-s2[i])/abs(s1[i]-s2[i]); // 不等,比较第一个不同的字符
}
字符串寻找字符
- 1. 在字符串
s中正向寻找字符c
char * strchr(char *s, char c)
{i = 0;while (s[i] != '\0' && s[i] != c) // 循环跳过非c字符i++;// 在循环结束后if (s[i] == '\0') // 当s不包含字符c则在s[i]即串尾return 0;else // 当s[i]==c则返回s[i]return &s[i];
}
- 2. 在字符串
s中反向寻找字符c
char * strrchr(char *s, char c)
{i = 0;while (s[i] != '\0') i++; // 获得s字符串的长度while (s[--i] != '\0' && s[i] != c); // 循环反向跳过非c字符// 在循环结束后if (s[i] == '\0') // 当s不包含字符c则在串尾结束return 0;else // 若成功则返回相应位置return &s[i];
}
举例,在 s = [Hello world\0] 中寻找 o:

寻找字符 o,strchar(s, 'o') 返回 4;
反向寻找 o,strchar(s, 'o') 返回 7。
C++的字符串类 String
除了采用标准字符串以外,还可以采用字符串类 String 来表示和存储字符串,以适应字符串的长度动态变化。
在 String 类中,字符串不再是以字符数组 char S[M] 这种形式来直接出现,而是采用一种动态变长的存储结构。
String 类是通过实例化标准模板库中的 STL 的 basic_string 而得到的。如下:
typedef basic_string <char> string;
它的存储结构如下:
private: // 具体实现的字符串存储结构char *str; // 字符指针表示的串实体int size; // 字符串长度
public: // 成员函数String(char *s); // 构构子~String(); // 析构子String operator=(String & s); // 赋值String operator+(String); // 拼接String substr(int index, int cout); // 子串int find(char c, int start); // 查找...
字符串类运算
| 操作类别 | 方法 | 描述 |
|---|---|---|
| 子串 | substr | 返回一个串的子串 |
| 拷贝 / 交换 | copy | 将一个串拷贝到另一个串中 |
| swap | 交换两个串的内容 | |
| 赋值 | assign | 把一个串、一个字符、一个子串赋值给另一个串中 |
| = | 把一个串或一个字符赋值给另一个串中 | |
| 插入 / 追加 | insert | 在给定位置插入一个字符、多个字符或串 |
| += | 将一个字符或串追加到另一个串后 | |
| append | 将一个或多个字符,或串追加在另一个串后 | |
| 拼接 | + | 通过将一个串放置在另一个串后面来构建新的新串 |
| 查询 | find | 找到并返回一个子序列的开始位置 |
| 替换 / 清除 | replace | 替换一个指定字符或一个串的子串 |
| clear | 清除串中的所有字符 | |
| 统计 | size | 返回串中字符的数目 |
| length | 返回size() | |
| max_size | 返回串允许的最大长度 |
构造算子
String 类有多个构造函数。构造一个带有初始值的 String 类可以参照以下方法:
String::String(char *s){ // 确定新字符串需要的空间,初始值为 char *ssize = strlen(s); // 新字符串的长度由标准字符串函数 strlen(s) 确定str = new char [size+1]; // 在动态存储区域开辟一块空间,用于存储初值s,包括结束符assert(str != '\0'); // 开辟空间不成功时,运行异常,退出strcpy(str, s); // 在空间申请成功后,用标准字符串函数strcpy将s完全复制到指针str所指的存储空间
}
例如,我们可以通过上面的带参数的构造函数通过 String s1("hello"); 定义一个 String 类的变量 s1,初始值为 hello。那么我们就可以申请一个容纳下 hello 的空间来将 hello 容纳进去,并且将 size 设置成相应的大小。
String s1("hello");private:char *s;size_t size; // 值为5
赋值算子
String String::operator=(String& s){ // 参数s将被赋值并覆盖本串。if (size != s.size){ // 比较本串和参数串s的大小:若本串和参数串长度不一致,则释delete [] str; // 放原本的串的存储空间str = new char [s.size+1]; // 按照参数s的大小申请新的空间,并把参数s的串值复制到本串中assert(str!=0);size=s.size;}strcpy(str, s.str); // 将参数串s赋值到本串return *this; // 返回得到的字符串
}
例如,我们通过构造函数构造一个串 s2,它的初值为 hello world 并通过 String s2("hello world"); s1=s2; 将这个值赋值给 s1。而 s1 此前已经被赋值 hello,所以可以看到 hello 的空间不足以存放新的值 hello world,所以将原本的空间释放掉、申请一个新的空间来容纳新值。

提取子串
// 提取子串的函数是将本串从index开始提取连续的count个字符 作为子串返回,放到temp中
String String::Substr(int index, int count){ // 取出一自下表index开始长度为count的子串返回int i;int left = size - index; // 本串自下标index开始到串尾的长度为leftString temp; char *p *q;if (index >= size) // 若下标index超过本串实际串长,则返回空串;return temp;if (count > left) // 若count超过自index开始剩余的子串长度count = left; // 则count截取为剩余长度delete [] temp.str; // 释放原来的存储空间temp.str = new char [count+1];assert(temp.str != 0); // 若开辟动态存储空间失败,则退出p = temp.str; // 若指针p指向目前暂无内容的字符数组的首字符处q = &str[index]; // 指针q指向本实例串的str数组的下标index字符for (i=0; i<count; i++) // 从index开始逐个提取字符到串temp中*p++ = *q++;*p = 0; // 循环结束后,让temp.str的结尾为 '\0'temp.size = count;return temp;
}
例如,我们可以通过 s2 = s1.substr(6 ,5) 从串 s1 hello world 的第6个位置开始,连续提取5个字符形成子串 world 赋值给 s2。
模式匹配
概念
模式匹配( Pattern Matching ),在目标文本 T 中寻找和定位一个给定模式 P( Pattern )的过程。
应用
模式匹配 有着非常广泛的应用,例如:
- 进行文本编辑时对特定词语、语句的查找;
- 大文本(诸如,句子、段落或书本)中定位特定的模式;
- UNIX / Linux:sed、awk、grep;
- 在生物信息方面,对DNA信息的提取;
- 用于确认是否具有某种特定形式的结构:
- 函数式语言
- …
分类
根据匹配结果的精确性,模式匹配 可以分为 精确匹配 和 近似匹配。
精确匹配
精确匹配( Extract String Matching ),若目标 T 中至少存在一处与模式 P 完全相同的子串,则称为匹配成功。
根据模式的不同,可以进一步的分为:
- 单选模式
例如,Set; - 多选模式
例如,包含通配符的S?t - 正则表达式
单选模式
给定模式串 P,在目标字符串 T 中搜索与模式 P 全同的子串,简称为 配串。如果找到,则返回 T 中第一个 P 的配串的首地址。

因为模式匹配频繁用于文本的模式查找,所以效率是衡量模式匹配算法的一个重要指标。因此,存在许多种用于模式匹配的算法。
这里列出一些常用的单选模式的字符串匹配算法,包含每个算法的预处理时间和匹配时间:

朴素匹配算法
朴素 匹配算法( Native / Brute Force ),本质上是穷举,尝试所有匹配的可能。
假设 T = t0t1t2…tn, P = p0p2…pm-1。i, j 分别表示 T 和 P 当前字符的下标,在目标字符串 T 中搜索与模式 P 的配串:
- 将模式从头与目标串的第 i 个字符开始比较:若相等,则继续逐个比较后续字符;
- 匹配成功( p0 = tk,p1 = tk+1,…,pm-1 = tk+m-1),即 T.substr(k, m) == P;
- 若一趟匹配过程发生失配( pj != ti ),则将 P 整体右移1位开始下一趟的匹配
例如,存在目标字符串 T = ababababababb 和模式串 P = abababb:

- 将P从0开始与T的第 i 个字符开始比较:若相等,则继续逐个比较后续字符;在第6个字符发生失配( P6 != T6),将P整体右移1位开始下一趟的匹配;
- 将P从1开始与T的第 i 个字符开始比较:在第1个字符发生失配(P0 != T1 ),将P整体右移1位开始下一趟的匹配;
- 重复上述步骤,直至 T.substr(k, m) == P 匹配成功或者匹配失败。
例如,存在目标字符串 T = aaaaaaaaaab 和模式串 P = aaaaaab:

- 将P从0开始与T的第 i 个字符开始比较:若相等,则继续逐个比较后续字符;在第6个字符发生失配( P6 != T6),将P整体右移1位开始下一趟的匹配;
- 将P从1开始与T的第 i 个字符开始比较:在第1个字符发生失配(P6 != T7 ),将P整体右移1位开始下一趟的匹配;
- 重复上述步骤,直至 T.substr(k, m) == P 匹配成功或者匹配失败。
朴素模式 的匹配算法实现如下:
int g, j;int FindPattern(string T, string P, int startindex)for (int g=startindex; g<=T.length()-P.length(); g++){ // g为T的游标,用模板P和目标T的第g位置子串进行比较for (int j=0; ((j<P.length()) && (T[g+j]==P[j])); j++);if (j==P.length())return g;}return (-1); // for循环结束,或者,startindex溢出,匹配失败
}
朴素模式 的匹配算法的时间复杂度分析如下:
-
最差情形

-
最佳情形


KMP 算法
Knuth - Morris - Pratt( KMP )发现每个字符对应的 k 值仅依赖于模式 P 本身,与目标串 T 无关。
1970年,S.A.Cook 在进行抽象机的理论研究时证明了最差情况下模式匹配可在 O(N+M) 时间内完成。
D.E.Knuth 和 V.R.Pratt 以 Cook理论为基础,构造了一种在 O(N+M) 时间内进行模式匹配的方法。
与此同时,J.H.Morris 在开发文本编辑器时为了避免检索文本时的回溯,也得到了同样的算法。
长度为m的模式P,P=p0p1p2p3…pm-1。特征向量N表示模式P的字符分布特征,由m个特征数nj组成 N = n0n1n2n3…nm-1。
特征向量,简称 N向量。在很多文献中也称为 next 数组,每个特征数 nj 对应 next 数组的一个元素。
【还是没搞懂KMP算法的思想…此处略…】
近似匹配
近似匹配( Approximate String Matching ),若模式 P 与目标 T(或其子串)存在某种程度的相似,则称为匹配成功。
字符串相似度通常定义串变换所需基本操作数目。
字符串基本操作包括 插入、删除 和 替换 三种操作。
参考链接
数据结构与算法 ↩︎
详解计算机中的字、字节(Byte)、比特(bit)及它们之间的关系 ↩︎
相关文章:
数据结构与算法 | 第四章:字符串
本文参考网课为 数据结构与算法 1 第四章字符串,主讲人 张铭 、王腾蛟 、赵海燕 、宋国杰 、邹磊 、黄群。 本文使用IDE为 Clion,开发环境 C14。 更新:2023 / 11 / 12 数据结构与算法 | 第四章:字符串 字符串概念字符串字符字符…...
2023-11-rust-struct
struct 类似 schema。 ts的interface 和type struct MyStruct {width: i32,height: i32, } 创建实例 let eg1 MyStruct {width: 23,height: 22,}; struct 可以有自己的方法,并且默认第一个参数是该实例 impl MyStruct {fn can_hold(&self, instance: &…...
Docker容器编排
文章目录 基本概念Docker ComposeSwarm分布式NodeTaskservice集群搭建弹性伸缩 基本概念 针对容器生命周期的管理,对容器生命周期进行更方便更快捷的方式进行管理。 依赖管理:当一个容器必须在另一个容器运行完成后,才能运行时,…...
计算机中丢失mfc140u.dll怎么解决
mfc140u.dll是一个Microsoft Visual C库文件,主要用于MFC(Microsoft Foundation Class)应用程序的开发。它包含了MFC应用程序所需的一些常用功能,如对话框、窗口、菜单等。当mfc140u.dll丢失时,可能会导致MFC应用程序无…...
postman设置动态token, 每次登录更新token
postman设置动态token, 每次登录更新token 文章目录 postman设置动态token, 每次登录更新token问题1. 设置全局变量2. 新建登录接口3. 设置脚本4. 切换环境5. 配置动态token 问题 token过期时间一般比较短, 每次使用postman调用接口都token非常麻烦 实现token过期后, 调用一次…...
架构师范文(AI写作)两篇
请点击↑关注、收藏,本博客免费为你获取精彩知识分享!有惊喜哟!! 架构师范文-论区块链技术及应用 2022年3月,我参与了某集团内部一款基于区块链技术的数字资产管理平台,该平台是为了方便管理公司旗下的各种…...
基于SSM的电子病历系统
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...
一次sougo workflow库的使用过程
安装就是常规的make install tutorial http_echoserver实现一下,在macos上实现 cmakelist.txt cmake_minimum_required(VERSION 3.6)set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Release")project(mainLANGUAGES C CXX )set(CMAKE_RUNTIME_OUTP…...
macOS Big Sur(macos11版本)
macOS Big Sur是苹果推出的最新操作系统,具有以下特点: 全新的设计风格:Big Sur采用了全新的设计语言,包括更加圆润的窗口和控件、更加鲜明的色彩和更加简洁的界面。这种设计风格使得操作系统更加美观和易用。强大的性能表现&…...
泛微E-Office信息泄露漏洞复现
简介 Weaver E-Office是中国泛微科技(Weaver)公司的一个协同办公系统。 Weaver E-Office 9.5版本存在安全漏洞。攻击者利用该漏洞可以访问文件或目录。 漏洞编号:CVE-2023-2766 漏洞复现 FOFA语法: app"泛微-EOffice&qu…...
-bash: sudo: command not found的解决方法
在 Linux 系统中,使用 sudo 命令时提示 “command not found”,首先执行以下命令看一下 /etc/sudoers.d 文件是否存在: find /etc/sudoers.d1)如果返回 No such file or directory,就说明系统没有安装sudo,…...
CMOS介绍
1 二极管 2 CMOS 2.1 栅极、源极、漏极 2.2 内部结构 2.2 导电原理 - 原理:1.通过门级和衬底加一个垂直电场Ev,从而在两口井之间形成反形层2.如果加的电场足够强,反形层就可以把source(源极)和drain(漏极…...
《软件工程与计算》期末考试真题范例及答案
今天分享一套针对《软件工程与计算》这本书的真题案例,有关《软件工程与计算》23章内容的重点知识整理,已经总结在了博客专栏中,有需要的自行阅读: 《软件工程与计算》啃书总结https://blog.csdn.net/jsl123x/category_12468792.…...
springboot高校全流程考勤系统-计算机毕设 附源码 27637
Springboot高校全流程考勤系统 摘 要 本文针对高校考勤等问题,对其进行研究分析,然后开发设计出高校全流程考勤系统以解决问题。高校全流程考勤系统系统主要功能模块包括:考勤签到、课程信息、考勤情况、申请记录列表等,系统功能设…...
大二第四周总结——用原生js封装一个分页器
用原生js封装一个分页器 起因:这次项目还是用原生的js来写的,我负责的是后台,分页是后台最常见的一个功能了,于是干脆封装一下,废话少说,直接上代码 这里是基本的样式 .pagination {display: flex;width: 600px;hei…...
智能AI系统ChatGPT系统源码+支持GPT4.0+支持ai绘画(Midjourney)/支持OpenAI GPT全模型+国内AI全模型
一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…...
ARM Linux 基础学习 / 系统相关,文件系统,文件属性
编辑整理 by Staok。 本文部分内容摘自 “100ask imx6ull” 开发板的配套资料(如 百问网的《嵌入式Linux应用开发完全手册》,在 百问网 imx6ull pro 开发板 页面 中的《2.1 100ASK_IMX6ULL_PRO:开发板资料》或《2.2 全系列Linux教程…...
nginx https 如何将部分路径转移到 http
nginx https 如何将部分路径转移到 http 我有一个自己的网站,默认是走的 https,其中有一个路径需要走 http。 实现 在 nginx 的配置文件 https 中添加这个路径,并添加一个 rewrite 的指令。 比如我需要将 tools/iphone 的路径转成 http&am…...
算法通关村第八关-白银挑战二叉树的深度和高度问题
大家好我是苏麟 , 今天说说几道二叉树深度和高度相关的题目 . LeetCode给我们造了一堆的题目,研究一下104、110和111三个题,这三个颗看起来挺像的,都是关于深度、高度的。 最大深度问题 描述 : 二叉树的 最大深度 是指从根节点到最远叶子…...
使用LogBack替换Log4j
目录 1.删除log4j有关的依赖,添加logBack依赖 2.删除log4j配置文件,增加logback.xml配置文件 3.更改application.yml配置文件,log文件指向logback.xml 4.重启 1.删除log4j有关的依赖,添加logBack依赖 <dependency><gr…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
