当前位置: 首页 > news >正文

数据结构与算法 | 第四章:字符串

本文参考网课为 数据结构与算法 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 编码
      支持多种东方语言:GB2312BIG5JIS 等。不同国家/地区制定不同的标准,不同 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

在这里插入图片描述
寻找字符 ostrchar(s, 'o') 返回 4
反向寻找 ostrchar(s, 'o') 返回 7


C++的字符串类 String

除了采用标准字符串以外,还可以采用字符串类 String 来表示和存储字符串,以适应字符串的长度动态变化。

String 类中,字符串不再是以字符数组 char S[M] 这种形式来直接出现,而是采用一种动态变长的存储结构。

String 类是通过实例化标准模板库中的 STLbasic_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 中寻找和定位一个给定模式 PPattern )的过程。


应用

模式匹配 有着非常广泛的应用,例如:

  • 进行文本编辑时对特定词语、语句的查找;
    • 大文本(诸如,句子、段落或书本)中定位特定的模式;
    • 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 的配串:

  1. 将模式从头与目标串的第 i 个字符开始比较:若相等,则继续逐个比较后续字符;
  2. 匹配成功( p0 = tk,p1 = tk+1,…,pm-1 = tk+m-1),即 T.substr(k, m) == P;
  3. 若一趟匹配过程发生失配( pj != ti ),则将 P 整体右移1位开始下一趟的匹配

例如,存在目标字符串 T = ababababababb 和模式串 P = abababb

在这里插入图片描述

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

例如,存在目标字符串 T = aaaaaaaaaab 和模式串 P = aaaaaab

在这里插入图片描述

  1. 将P从0开始与T的第 i 个字符开始比较:若相等,则继续逐个比较后续字符;在第6个字符发生失配( P6 != T6),将P整体右移1位开始下一趟的匹配;
  2. 将P从1开始与T的第 i 个字符开始比较:在第1个字符发生失配(P6 != T7 ),将P整体右移1位开始下一趟的匹配;
  3. 重复上述步骤,直至 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 - PrattKMP )发现每个字符对应的 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(或其子串)存在某种程度的相似,则称为匹配成功。

字符串相似度通常定义串变换所需基本操作数目。

字符串基本操作包括 插入删除替换 三种操作。



参考链接


  1. 数据结构与算法 ↩︎

  2. 详解计算机中的字、字节(Byte)、比特(bit)及它们之间的关系 ↩︎

相关文章:

数据结构与算法 | 第四章:字符串

本文参考网课为 数据结构与算法 1 第四章字符串&#xff0c;主讲人 张铭 、王腾蛟 、赵海燕 、宋国杰 、邹磊 、黄群。 本文使用IDE为 Clion&#xff0c;开发环境 C14。 更新&#xff1a;2023 / 11 / 12 数据结构与算法 | 第四章&#xff1a;字符串 字符串概念字符串字符字符…...

2023-11-rust-struct

struct 类似 schema。 ts的interface 和type struct MyStruct {width: i32,height: i32, } 创建实例 let eg1 MyStruct {width: 23,height: 22,}; struct 可以有自己的方法&#xff0c;并且默认第一个参数是该实例 impl MyStruct {fn can_hold(&self, instance: &…...

Docker容器编排

文章目录 基本概念Docker ComposeSwarm分布式NodeTaskservice集群搭建弹性伸缩 基本概念 针对容器生命周期的管理&#xff0c;对容器生命周期进行更方便更快捷的方式进行管理。 依赖管理&#xff1a;当一个容器必须在另一个容器运行完成后&#xff0c;才能运行时&#xff0c;…...

计算机中丢失mfc140u.dll怎么解决

mfc140u.dll是一个Microsoft Visual C库文件&#xff0c;主要用于MFC&#xff08;Microsoft Foundation Class&#xff09;应用程序的开发。它包含了MFC应用程序所需的一些常用功能&#xff0c;如对话框、窗口、菜单等。当mfc140u.dll丢失时&#xff0c;可能会导致MFC应用程序无…...

postman设置动态token, 每次登录更新token

postman设置动态token, 每次登录更新token 文章目录 postman设置动态token, 每次登录更新token问题1. 设置全局变量2. 新建登录接口3. 设置脚本4. 切换环境5. 配置动态token 问题 token过期时间一般比较短, 每次使用postman调用接口都token非常麻烦 实现token过期后, 调用一次…...

架构师范文(AI写作)两篇

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 架构师范文-论区块链技术及应用 2022年3月&#xff0c;我参与了某集团内部一款基于区块链技术的数字资产管理平台&#xff0c;该平台是为了方便管理公司旗下的各种…...

基于SSM的电子病历系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

一次sougo workflow库的使用过程

安装就是常规的make install tutorial http_echoserver实现一下&#xff0c;在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是苹果推出的最新操作系统&#xff0c;具有以下特点&#xff1a; 全新的设计风格&#xff1a;Big Sur采用了全新的设计语言&#xff0c;包括更加圆润的窗口和控件、更加鲜明的色彩和更加简洁的界面。这种设计风格使得操作系统更加美观和易用。强大的性能表现&…...

泛微E-Office信息泄露漏洞复现

简介 Weaver E-Office是中国泛微科技&#xff08;Weaver&#xff09;公司的一个协同办公系统。 Weaver E-Office 9.5版本存在安全漏洞。攻击者利用该漏洞可以访问文件或目录。 漏洞编号&#xff1a;CVE-2023-2766 漏洞复现 FOFA语法&#xff1a; app"泛微-EOffice&qu…...

-bash: sudo: command not found的解决方法

在 Linux 系统中&#xff0c;使用 sudo 命令时提示 “command not found”&#xff0c;首先执行以下命令看一下 /etc/sudoers.d 文件是否存在&#xff1a; find /etc/sudoers.d1&#xff09;如果返回 No such file or directory&#xff0c;就说明系统没有安装sudo&#xff0c…...

CMOS介绍

1 二极管 2 CMOS 2.1 栅极、源极、漏极 2.2 内部结构 2.2 导电原理 - 原理&#xff1a;1.通过门级和衬底加一个垂直电场Ev&#xff0c;从而在两口井之间形成反形层2.如果加的电场足够强&#xff0c;反形层就可以把source&#xff08;源极&#xff09;和drain&#xff08;漏极…...

《软件工程与计算》期末考试真题范例及答案

今天分享一套针对《软件工程与计算》这本书的真题案例&#xff0c;有关《软件工程与计算》23章内容的重点知识整理&#xff0c;已经总结在了博客专栏中&#xff0c;有需要的自行阅读&#xff1a; 《软件工程与计算》啃书总结https://blog.csdn.net/jsl123x/category_12468792.…...

springboot高校全流程考勤系统-计算机毕设 附源码 27637

Springboot高校全流程考勤系统 摘 要 本文针对高校考勤等问题&#xff0c;对其进行研究分析&#xff0c;然后开发设计出高校全流程考勤系统以解决问题。高校全流程考勤系统系统主要功能模块包括&#xff1a;考勤签到、课程信息、考勤情况、申请记录列表等&#xff0c;系统功能设…...

大二第四周总结——用原生js封装一个分页器

用原生js封装一个分页器 起因&#xff1a;这次项目还是用原生的js来写的&#xff0c;我负责的是后台&#xff0c;分页是后台最常见的一个功能了&#xff0c;于是干脆封装一下,废话少说&#xff0c;直接上代码 这里是基本的样式 .pagination {display: flex;width: 600px;hei…...

智能AI系统ChatGPT系统源码+支持GPT4.0+支持ai绘画(Midjourney)/支持OpenAI GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…...

ARM Linux 基础学习 / 系统相关,文件系统,文件属性

编辑整理 by Staok。 本文部分内容摘自 “100ask imx6ull” 开发板的配套资料&#xff08;如 百问网的《嵌入式Linux应用开发完全手册》&#xff0c;在 百问网 imx6ull pro 开发板 页面 中的《2.1 100ASK_IMX6ULL_PRO&#xff1a;开发板资料》或《2.2 全系列Linux教程&#xf…...

nginx https 如何将部分路径转移到 http

nginx https 如何将部分路径转移到 http 我有一个自己的网站&#xff0c;默认是走的 https&#xff0c;其中有一个路径需要走 http。 实现 在 nginx 的配置文件 https 中添加这个路径&#xff0c;并添加一个 rewrite 的指令。 比如我需要将 tools/iphone 的路径转成 http&am…...

算法通关村第八关-白银挑战二叉树的深度和高度问题

大家好我是苏麟 , 今天说说几道二叉树深度和高度相关的题目 . LeetCode给我们造了一堆的题目&#xff0c;研究一下104、110和111三个题&#xff0c;这三个颗看起来挺像的&#xff0c;都是关于深度、高度的。 最大深度问题 描述 : 二叉树的 最大深度 是指从根节点到最远叶子…...

使用LogBack替换Log4j

目录 1.删除log4j有关的依赖&#xff0c;添加logBack依赖 2.删除log4j配置文件&#xff0c;增加logback.xml配置文件 3.更改application.yml配置文件&#xff0c;log文件指向logback.xml 4.重启 1.删除log4j有关的依赖&#xff0c;添加logBack依赖 <dependency><gr…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...