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

【数据结构】【线性表】特殊的线性表-字符串

目录

字符串的基本概念        

字符串的三要素

字符串的基本概念

串的编码

串的实现及基本运算

顺序串的实现

串的静态数组实现

串的动态数组的实现

顺序存储的四种方案

链式串的实现

基本运算

方案三

方案一


字符串的基本概念        

        数据结构千千万,但距离我们最近的还是字符串。在这里我们定义:有限个字符组成的序列为字符串。在大多数人看来,字符串仅仅是一个char类型的数组,但在作者看来,数组也是一种特殊的线性表。回想顺序表、顺序栈、顺序队列这些都和数组有着千丝万缕的联系。但在我们这里要讲的字符串,它的格式不仅仅是数组格式,数组格式只是串格式的众多种类中的一种。

        我们回顾数据结构的三要素:逻辑结构、物理结构和基本运算。线性表是指元素之间的逻辑结构为线性的一系列的数据结构,其特点是一对一。类似的,字符串各个元素之间的逻辑结构也可以视为线性,因此字符串是一种特殊的线性表。

字符串的三要素

  1. 逻辑结构:线性结构
  2. 物理结构:顺序存储/链式存储
  3. 基本运算
    1. StrCopy(&T,S)复制串,将串S复制到串T;
    2. StrEmpty(S)串判空,判断串S是否为空串;
    3. StrLength(S)求串长,求串S的长度;
    4. ClearStr(S)清空串,清空串S,使其成为空串;
    5. DestroyStr(&S)销毁串,清空串并释放其内存空间;
    6. ConcatStr(&T,S1,S2)串连两个串,在S1串后面链接上S2成为一个串T;
    7. SubString(&Sub,S,pos,len)求子串,求串S以pos为起点,长度为len的子串;
    8. StrCompare(S,T)比较串,比较串S与T,S>T则返回值大于0;S=T则返回值等于0;S<T则返回值小于0;
    9. Index(S,T)定位子串,如果主串S中存在与T相同的子串,则返回主串第一次出现子串的第一个位置;

上述基本操作涉及到一些串的相关名词,在这里作一下定义说明,没有疑问的可跳过。

字符串的基本概念

字符串:有限个字符组成的序列

  1. 串长:有限字符的个数n
  2. 空串:有限字符个数为0
  3. 空格串:串内所有字符均为空格;例如:“   ”
  4. 主串和子串:这是一个相对概念,一般来说,把一个完整的字符串当成主串,而子串是从主串中任意提出来的连续字符组成的序列
    例如:

    a="qwer1314";
    b="qwer"
    c="1314",
    d="wer1",
    在这里b c d均是a的子串

        注意空串和空格串,空串里面没有一个字符,而空格串是包含了字符,只不过这个字符是空格。

串的编码

  1. 英文字符:ASCII码等。
  2. 中英文字符:UTF8、UTF16、GB2312等。

        我们知道,计算机的存储是二进制的,也就是说无论什么字符,其存储的数据都是二进制,那么如何将二进制数与符号相对应,这就是我们的编码。编码是一种规则,一个二进制数通过这个规则对应表示一个字符。抽象理解成一个y=f(x)的函数,自变量x为二进制数,编码为映射规则f,因变量为字符集y。满足函数一一对应的性质。编码有多种多样的,例如BCD码,格雷码等。

        ASCII码是我们最常用的一种编码,其存储空间一般为1B。它包含了我们常见的大部分英文字符,例如26个大小写英文字母,数字,空格等。其具体的ASCII表在网上众多,我就不一一赘述了。

        UTF8、UTF16、GB2312都是包含了中英文字符的编码,在需要使用中文的体系中常用,但需要注意的是使用这几种的人数较多较杂,不像英文字符大部分人都用ASCII,这几种也很多人使用,因此我们在打开其他人的文件时很容易出现乱码,其主要原因就是你打开打编码方式与他写的编码方式不一致。因此当遇到乱码,应当及时更正打开文件的编码方式。

串的实现及基本运算

顺序串的实现

        顺序串即存储结构为连续顺序的字符串,和顺序表类似,其构建方法一般可以分为静态数组和动态数组两种。

串的静态数组实现

#define MaxSize 100;//定义最大分配空间为100个
typedef struct{char str[MaxSize];//定义静态字符数组int length;//定义串的实际长度
}SString;

         静态数组在分配得到时候固定了大小空间

串的动态数组的实现

typedef struct{char *str;int length;
}HString;

        动态数组只分配了数组的基址,大小可自己拓展。在应用过程中拓展需要用到malloc函数,同时销毁元素时也要手动free空间。

顺序存储的四种方案

        方案1是最常见的格式,也是一般字符串的默认格式,不包含表长元素,以'\0'作为结尾符号;

        方案2是我们默认使用的格式,前面是串的各个字符元素,最后存放表长元素;

        方案3是舍弃数组的第一个元素,使数组下标与字符的位序对其,最后存放表长元素;

        方案4不单独设置表长元素,将串的字符数组的第一个元素存放表长数据, 同时也让数组下标与字符位序对齐;但表长元素的数据类型是int,字符数组的数据类型是char,使用中有很多需要注意,因此实用性不是很好。

        四个方案相较而言方案3更具有优势,但方案1的普遍性更强。

链式串的实现

        链式串的物理结构类似于单链表,每个结点存放一组数据,并指向下一个结点,结构示意图:

        其中S是头结点,从1开始才是串的实际字符数据;当然采用无头结点的串也是可以的,只需要注意第一个结点特殊处理就行。

typedef struct StringNode{char str;//每个结点存储一个字符struct StringNode *next;//指向下一个结点
}StringNode,*String;

        一般而言我们会采用一个结点储存一个字符,但有些特殊情况下需要一个结点储存固定长度的字符,同时也节省空间。

typedef struct StringNode{char str[4];//每个结点存储4个字符struct StringNode *next;//指向下一个结点
}StringNode,*String;

基本运算

        在讲基本操作之前,我们先确定一下其串的格式,物理存储格式决定这基本运算的操作思路、步骤与顺序。从编程的逻辑性和简易性而言,方案三是最合适的。

        但又考虑到普遍的字符串存储格式是方案一:

         因此我们选择在方案三的基础上完成思路和源码的讲解,同时展示完整的方案一源码,在源码中简单讲解。

方案三

        方案三字符串结构体创建

#define MaxSize 100;//定义最大分配空间为100个
typedef struct{char str[MaxSize];//定义静态字符数组int length;//定义串的实际长度
}SString;
/*初始化串*/
void InitString(SString &S){for(int i=0;i<MaxSize;i++)//将所有值设定为字符串终止符,也可以是别的没歧义的内容S.str[i]='\0';S.length=0;//初始化字符串长度为0
}

         复制串,将串S复制得到串T

void StrCopy(SString &T,SString S){T.length=S.length;for(int i=1;i<=T.length;i++){T.str[i]=S.str[i];}
}

        串判空,判断串是否为空串,是返回true,不是返回false

bool StrEmpty(SString S){if(S.length==0)//字符串长度为0则为空字符串return true;else if(S.length>0)return false;
}

         求串长,在这个格式下有点多此一举,但也还是说明一下吧

int StrLength(SString S){return S.length;
}

        清空串,使其成为空串,但其实在这里没办法真的成为空,毕竟空间就在那,一般操作方式是给每个字符空间赋值为特殊值,例如0或者'\0',然后修改表长。对于char数据类型建议赋值为'\0';对于其他int或者float建议赋值为0

void ClearString(SString &S){for(int i=0;i<=S.length;i++)S.str[i]='\0';S.length=0;
}

         销毁串,因为这个结构采用的是静态数组,静态数组不需要手动释放空间,内存会在超出变量作用域时自动释放空间。

        连接串,串连两个串,在S1串后面连接上S2成为一个串T;

bool ConcatString(SString &T,SString S1,SSrting S2){T.length=S1.length+S2.length;//拼接后的长度if(T.length+1>MaxSize)//判断长度是否超限return false;//长度超限,拼接失败for(int i=1;i<=S1.length;i++)//将S1的数据复制到TT.str[i]=S1.str[i];for(int i=1;i<=S2.length;i++)//将S2的数据复制到S1后面T.str[S1.length+i]=S2.str[i];return true;//拼接成功
}

        求子串,求主串S第pos位开始的长len的子串

bool SubString(SString &Sub,SString S,int pos,int len){if(pos+len-1>S.length)//判断子串是否越界return false;//子串越界,获取子串失败Sub.length=len;//子串长度为lenfor(int i=1;i<len+1;i++)//读取子串并复制给SubSub.str[i]=S.str[i+pos-1];Sub.str[i]='\0';//给子串添加终止符return true;//获取子串成功
}

        StrCompare(S,T)比较串,比较串S与T,S>T则返回值大于0;S=T则返回值等于0;S<T则返回值小于0。

        有人就说了字符串怎么能比较呢?这也是作者刚开始疑惑的问题,字符串比什么,除了能比一不一样还能干嘛?所以在比较字符串之前一定要有比较的标准,制定比较标准时需要注意以下三个要点

  • 要不要考虑字符的大小写
  • 字符串的长度
  • 对于特殊字符和不同编码如何处理

 下面我们先制定字符串比较的规则:

  1. 比较对字符大小写敏感,直接按顺序比较字符在ASCLL的码值,先出现更大字符的串更大
  2. 考虑字符串长度,长串前缀与短串字符一致时,长串更大
  3. 不考虑特殊字符,默认均为ASCII码
int StrCompare(SString S,SString T){//遍历查找两个字符串每个位置的字符比较情况for(int i=1;i<=S.length && i<=T.length;i++){if(S.str[i]!=T.str[i])//字符不相同则相减并返回return S.str[i]-T.str.[i];}return S.length-T.length;//
}

定位子串, 如果主串S中存在与T相同的子串,则返回主串第一次出现子串的第一个位置。

int IndexStr(SString S,SString T){int m=S.length;int n=t.length;int flag;SString Sub;for(int i=1;i<=n-m+1;i++){/*取出字符串S中长度为n的子串*/if(i+n-1>S.length)//判断子串是否越界return 0;//子串越界,获取子串失败Sub.length=n;//子串长度为nfor(int j=1;j<=n;j++)//读取子串并复制给SubSub.str[j]=S.str[j+i-1];/*比较T与S的子串Sub*/for(int j=1;j<=S.length && j<=T.length;j++){if(S.str[j]!=Sub.str[j])flag=T.str[j]-Sub.str[j];}flag=S.length-T.length;/*判断两串是否相等*/if(flag==0)return i;}return 0;//没有到与T相等的子串
}

 上述代码中有求子串和比较子串的操作,我们采用源码表示,但也可以直接用函数:

int IndexStr(SString S,SString T){int m=S.length;int n=t.length;bool flag;SString Sub;for(int i=1;i<=n-m+1;i++){/*取出字符串S中长度为n的子串*/flag=SubString(Sub,S,i,n);if(flag==false)return 0;//子串违法/*判断两串是否相等*/if(StrCompare(T,Sub)==0)return i;}return 0;//没有到与T相等的子串
}
方案一

方案一是最常见的字符串类型例如:

char str[]="qwer1314";

 这种方式不需要结构体,同时也是我们在大多数场合输入字符串的默认格式,因此在这里我们再次进行代码讲解;

/*将字符串S复制给T*/
void StrCopy(char *S,char *T){int i=0;while(S[i]!='\0'){T[i]=S[i];i++;}T[i]='\0';
}
/*判定字符串S是否为空*/
bool StrEmpty(char *S){if(S[0]=='\0')return true;elsereturn false;
}
/*求字符串S的长度*/
int StrLength(char *S){int len=0;while(S[len]!='\0'){len++;}return len;
}
/*清空字符串*/
void ClearString(char *S){int i=0;while(S[i]!='\0'){S[i]='\0';i++;}
}
/*串联两个字符串*/
char *ConcatStr(const char *str1, const char *str2) {// 检查输入是否为NULLif (str1 == NULL || str2 == NULL) {return NULL;}// 计算新字符串的长度int len1 = StrLength(str1);int len2 = StrLength(str2);int newLen = len1 + len2 + 1; // 分配内存char *result = (char *)malloc(newLen * sizeof(char));if (result == NULL) {// 内存分配失败return NULL;}// 复制第一个字符串到结果中int i = 0;while (i < len1) {result[i] = str1[i];i++;}// 连接第二个字符串到结果中int j = 0;while (j < len2) {result[i + j] = str2[j];j++;}// 添加终止符result[i + j] = '\0';return result;
}
/*求子串*/
char *SubString(char *str, int pos, int len) {int length = StrLength(str);if (pos + len > length || pos < 0 || len < 0) {return NULL; // 检查边界条件}// 分配内存char *result = (char *)malloc((len + 1) * sizeof(char));if (result == NULL) {return NULL; // 检查内存分配是否成功}for (int i = 0; i < len; i++) {result[i] = str[pos + i];}result[len] = '\0'; // 添加字符串结束符return result;
}
/*比较字符串*/
int Strcompare(char *str1,char *str2){int len1=StrLength(str1),len2=StrLebgth(str2);for(int i=0;i<len1 && i<len2;i++){if(str1[i]!=str2[i])return str1[i]-str2[i];}return len1-len2;
}
/*定位字符串*/
int Index(char *str1,char *str2){int m=StrLength(str1);int n=StrLength(str2);bool flag;char *Sub;for(int i=1;i<=n-m+1;i++){/*取出字符串S中长度为n的子串*/Sub=SubString(S,i,n);if(flag==NULL)return 0;//子串违法/*判断两串是否相等*/if(StrCompare(S,Sub)==0)return i;}return 0;//没有到与T相等的子串
}

常见字符串操作:

将字符串转换成int

//字符串转化为int
int string_int(char *str) {if (str == NULL || *str == '\0') {// 输入为空或空字符串return 0;}int num = 0;int i = 0;int flag = 1;// 检查负号if (str[i] == '-') {flag = -1;i++;}// 转换数字部分while (str[i] >= '0' && str[i] <= '9') {int digit = str[i] - '0';// 检查是否会发生溢出if (num > (INT_MAX - digit) / 10) {// 发生溢出,返回0或其他错误值return 0;}num = num * 10 + digit;i++;}return flag * num;
}

将int转化为字符串

char *int_string(int num) {// 假设整数最多有11位(包括负号)char *str = (char *)malloc(12 * sizeof(char)); // 分配内存用于存储转换后的字符串if (str == NULL) {return NULL; // 如果内存分配失败,返回NULL}int i = 0; // 用于记录当前字符的位置int isNegative = 0; // 标记是否为负数if (num < 0) {isNegative = 1; // 如果是负数,设置标记并取绝对值num = -num;}// 将数字转换为字符串do {str[i++] = (num % 10) + '0'; // 将最低位的数字转换为字符并存储num /= 10; // 去掉已经处理的最低位} while (num > 0);if (isNegative) {str[i++] = '-'; // 如果是负数,添加负号}// 反转字符串for (int j = 0; j < i / 2; j++) { // 注意这里需要声明j的类型为intchar temp = str[j];str[j] = str[i - j - 1];str[i - j - 1] = temp;}// 添加字符串终止符str[i] = '\0';return str; // 返回转换后的字符串
}

将字符串转换成float

// 将字符串转换为浮点数的函数
float string_float(char *str) {// 如果输入为空或空字符串,返回0.0fif (str == NULL || *str == '\0') {return 0.0f;}// 初始化变量float num = 0.0f; // 最终结果int i = 0; // 当前字符索引int flag = 1; // 符号标志,1表示正数,-1表示负数int fractional_part = 0; // 是否处理小数部分的标志float fractional_divisor = 1.0f; // 小数部分的除数// 检查负号if (str[i] == '-') {flag = -1;i++;}// 转换数字部分和小数部分while (str[i] != '\0') {if (str[i] >= '0' && str[i] <= '9') {int digit = str[i] - '0'; // 将字符转换为数字if (fractional_part) {// 处理小数部分fractional_divisor *= 10.0f;num += digit / fractional_divisor;} else {// 处理整数部分if (num > (FLT_MAX - digit) / 10.0f) {// 发生溢出,返回0或其他错误值return 0.0f;}num = num * 10.0f + digit;}} else if (str[i] == '.' && !fractional_part) {// 遇到小数点,开始处理小数部分fractional_part = 1;} else {// 非法字符,直接返回当前结果break;}i++;}// 返回最终结果,考虑符号return flag * num;
}

将float转换为字符串

// 将浮点数转换为字符串的函数
char *float_string(float num) {// 假设浮点数最多有38位(包括负号、小数点和指数)char *str = (char *)malloc(40 * sizeof(char)); // 分配内存用于存储转换后的字符串if (str == NULL) {return NULL; // 如果内存分配失败,返回NULL}int i = 0; // 用于记录当前字符的位置int isNegative = 0; // 标记是否为负数if (num < 0) {isNegative = 1; // 如果是负数,设置标记并取绝对值num = -num;}// 处理整数部分int integerPart = (int)num; // 获取整数部分do {str[i++] = (integerPart % 10) + '0'; // 将整数部分逐位转换为字符并存储integerPart /= 10; // 去掉已经处理的最低位} while (integerPart > 0);if (isNegative) {str[i++] = '-'; // 如果是负数,添加负号}// 反转整数部分,使其按正确顺序排列for (int j = 0; j < i / 2; j++) {char temp = str[j];str[j] = str[i - j - 1];str[i - j - 1] = temp;}// 添加小数点str[i++] = '.';// 处理小数部分float fractionalPart = num - (int)num; // 获取小数部分int precision = 6; // 设置精度为6位小数for (int k = 0; k < precision; k++) {fractionalPart *= 10; // 将小数部分放大10倍int digit = (int)fractionalPart; // 获取当前最高位的小数str[i++] = digit + '0'; // 将小数转换为字符并存储fractionalPart -= digit; // 去掉已经处理的最高位小数}// 添加字符串终止符str[i] = '\0';return str; // 返回转换后的字符串
}

相关文章:

【数据结构】【线性表】特殊的线性表-字符串

目录 字符串的基本概念 字符串的三要素 字符串的基本概念 串的编码 串的实现及基本运算 顺序串的实现 串的静态数组实现 串的动态数组的实现 顺序存储的四种方案 链式串的实现 基本运算 方案三 方案一 字符串的基本概念 数据结构千千万&#xff0c…...

【AWS re:Invent 2024】一文了解EKS新功能:Amazon EKS Auto Mode

文章目录 一、为什么要使用 Amazon EKS Auto Mode&#xff1f;二、Amazon EKS自动模式特性2.1 持续优化计算成本2.2 迁移集群操作2.3 EKS 自动模式的高级功能 三、EKS Auto 集群快速创建集群配置四、查看来自 API 服务器的指标五、EKS 相关角色权限设置六、参考链接 一、为什么…...

HTTPS的工作过程

1.HTTPS协议原理 1.1HTTPS协议的由来 HTTP在传输网络数据的时候是明文传输的&#xff0c;信息容易被窃听甚至篡改&#xff0c;因此他是一个不安全的协议&#xff08;但效率高&#xff09;。在如今的网络环境中&#xff0c;数据安全是很重要的&#xff08;比如支付密码又或者各…...

Java并发编程学习之从资本家的角度看多线程和并发性(一)

目录 前言前置知识一、单线程时代二、为什么要有多线程&#xff0c;多线程的优点&#xff1f;三、使用多线程会遇到什么问题&#xff1f;四、多线程和并发编程的关系总结 前言 这篇文章是打开Java多线程和并发编程的大门的开始&#xff0c;如标题《从老板的角度看多线程和并发…...

基于STM32设计的智能宠物喂养系统(华为云IOT)_273

文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成【4】设计意义【5】国内外研究现状【6】摘要1.2 设计思路1.3 系统功能总结1.4 开发工具的选择【1】设备端开发【2】上位机开发1.5 参考文献1.6 系统框架图1.7 系统原理图1.8 实物图1.9…...

Mybatis-Plus的主要API

一、实体类操作相关API BaseMapper<T>接口 功能&#xff1a;这是 MyBatis - Plus 为每个实体类对应的 Mapper 接口提供的基础接口。它提供了一系列基本的 CRUD&#xff08;增删改查&#xff09;操作方法。例如insert(T entity)方法用于插入一条记录&#xff0c;d…...

Pillow:强大的Python图像处理库

目录 一、引言 二、Pillow 库的安装 三、Pillow 库的基本概念 四、图像的读取和保存 五、图像的基本属性 六、图像的裁剪、缩放和旋转 七、图像的颜色调整 八、图像的滤镜效果 九、图像的合成和叠加 十、图像的绘制 十一、示例程序&#xff1a;制作图片水印 十二、…...

Springboot定时任务详解

文章目录 Springboot定时任务详解一、引言二、cron表达式三、使用Scheduled注解1、开启定时任务2、添加定时任务 四、使用TaskScheduler接口1、注入TaskScheduler实例 五、集成Quartz框架1、集成Quartz 六、实际使用示例七、总结 Springboot定时任务详解 一、引言 在现代软件…...

【Linux】环境ChatGLM-4-9B 模型之 openai API 服务

一、摘要 最近看到 Function Call 比较感兴趣,它的核心是赋予大模型能够调用外部API的能力,能够解决大模型功能扩展性问题,允许模型调用外部数据库或API,提供特定领域的详细信息;解决信息实时性问题,模型可以实时获取最新数据;解决数据局限性问题,大模型训练数据虽多但…...

mobi文件转成pdf

将 MOBI 文件转换为 PDF 格式通常涉及两个步骤&#xff1a; 解析 MOBI 文件&#xff1a;需要提取 MOBI 文件的内容&#xff08;文本、图片等&#xff09;。将提取的内容转换为 PDF&#xff1a;将 MOBI 文件的内容渲染到 PDF 格式。 可用工具 kindleunpack 或 mobi&#xff1…...

Linux---对缓冲区的简单理解--第一个系统程序

前序&#xff1a; 首先先理解一下什么是回车与换行&#xff1b;回车和换行是两个概念&#xff0c;它们不是一个东西&#xff1b; 回车:光标回到开始&#xff1b;换行:换到下一行&#xff1b; 如下图&#xff1a; 行缓冲区 如何理解缓冲区问题&#xff1f; 可以认为&#xff0…...

word poi-tl 表格功能增强,实现表格功能垂直合并

目录 问题解决问题poi-tl介绍 功能实现引入依赖模版代码效果图 附加&#xff08;插件实现&#xff09;MergeColumnData 对象MergeGroupData 类ServerMergeTableData 数据信息ServerMergeTablePolicy 合并插件 问题 由于在开发功能需求中&#xff0c;word文档需要垂直合并表格&…...

鸿蒙实现数据管理

目录&#xff1a; 1、鸿蒙实现数据管理的三种方式2、用户首选项3、键值型数据管理3.1、获取KVManager实例&#xff0c;用于管理数据库对象3.2、创建并获取键值数据库3.3、调用put()方法向键值数据库中插入数据3.4、调用get()方法获取指定键的值3.5、调用delete()方法删除指定键…...

图片上传HTML

alioss sky:jwt:# 设置jwt签名加密时使用的秘钥admin-secret-key: itcast# 设置jwt过期时间admin-ttl: 7200000# 设置前端传递过来的令牌名称admin-token-name: tokenalioss:endpoint: ${sky.alioss.endpoint}access-key-id: ${sky.alioss.access-key-id}access-key-secret: $…...

golang 代发邮件支持附件发送,outlook案列,其他邮箱需要替换对应邮箱服务域名

GPT问答实例 import pandas as pd from openai.embeddings_utils import get_embedding, cosine_similarity import openai import os import logging as logger from flask_cors import CORS import os openai.api_key os.getenv(OPENAI_API_KEY)class Chatbot():def parse_…...

输出绝对值

输出绝对值 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 输入一个浮点数&#xff0c;输出这个浮点数的绝对值。 输入 输入一个浮点数&#xff0c;其绝对值不超过10000。 输出 输出这个浮点数的绝对…...

docker desktop打包配置国内镜像地址

打包遇到无法访问外网资源&#xff0c;直接配置国内镜像地址 直接加入如下代码就行&#xff1a; {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-m…...

鸿蒙Next学习-监听指定页面显示/页面生命周期

自定义组件监听页面生命周期 使用无感监听页面路由的能力&#xff0c;能够实现在自定义组件中监听页面的生命周期。 // Index.ets import { uiObserver, router, UIObserver } from kit.ArkUI;Entry Component struct Index {listener: (info: uiObserver.RouterPageInfo) &g…...

计算机网络 —— HTTPS 协议

前一篇文章&#xff1a;计算机网络 —— HTTP 协议&#xff08;详解&#xff09;-CSDN博客 目录 前言 一、HTTPS 协议简介 二、HTTPS 工作过程 1.对称加密 2.非对称加密 3.中间人攻击 4.引入证书 三、HTTPS 常见问题 1.中间人能否篡改证书&#xff1f; 2.中间人能否调…...

Oracle之表空间迁移

问题背景&#xff1a;一个数据表随着时间的累积&#xff0c;导致所在表空间占用很高&#xff0c;里面历史数据可以清除&#xff0c;保留近2个月数据即可 首先通过delete删除了2个月以前的数据。 按网上的教程进行空间压缩&#xff0c;以下sql在表所在用户执行: -- 允许表重新…...

web组态可视化编辑器

随着工业智能制造的发展&#xff0c;工业企业对设备可视化、远程运维的需求日趋强烈&#xff0c;传统的单机版组态软件已经不能满足越来越复杂的控制需求&#xff0c;那么实现web组态可视化界面成为了主要的技术路径。 行业痛点 对于软件服务商来说&#xff0c;将单机版软件转…...

SpringMVC纯注解快速开发

此文章适合具有一定的java基础的同学看哦&#xff0c;如果有看不懂的基本代码还是先补补java基础哦。 此教程带您不使用xml文件而是纯注解开发&#xff0c;易懂、快捷、迅速&#xff0c;从0开始搭建&#xff0c;很快就能构建起一个SpringMVC项目&#xff0c;能学到两种使用tom…...

[读论文] Compositional 3D-aware Video Generation with LLM Director

Abstract 近年来&#xff0c;通过强大的生成模型和大规模互联网数据&#xff0c;文本到视频生成领域取得了显著进展。然而&#xff0c;在生成视频中精确控制单个概念&#xff08;如特定角色的动作和外观、视角的移动&#xff09;方面&#xff0c;仍存在巨大挑战。为此&#xff…...

FFmpeg 4.3 音视频-多路H265监控录放C++开发十八,ffmpeg解复用

为啥要封装和解封装呢&#xff1f; 1.封装就相当于将 h264 和aac 包裹在一起。既能播放声音&#xff0c;也能播放视频 2.在封装的时候没指定编码格式&#xff0c;帧率&#xff0c;时长&#xff0c;等参数&#xff1b;特别是视频&#xff0c;可以将视频帧索引存储&#xff0c;…...

ubuntu系统安装docker

1、 安装必要的依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common2、添加 Docker 的官方 GPG 密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -3、添加 Docker 的 APT 源 sudo add-apt-repos…...

STM32 BootLoader 刷新项目 (十三) Python上位机介绍

STM32 BootLoader 刷新项目 (十三) Python上位机介绍 大家好&#xff0c;这是我们STM32 BootLoader的最后一篇文章了&#xff0c;讲述用Python写的上位机&#xff0c;也更新了半年时间了&#xff0c;谢谢大家的支持&#xff0c;到目前为止&#xff0c;已经更新了12篇文章了&am…...

美畅物联丨智能监控,高效运维:视频汇聚平台在储能领域的实践探索

在当今全球能源格局不断变化的大背景下&#xff0c;对清洁能源的需求正以惊人的速度增长。储能项目作为平衡能源供需、提升能源利用效率的关键环节&#xff0c;其规模和复杂度也在不断攀升。在储能项目的运营管理过程中&#xff0c;安全监控、设备运维以及数据管理等方面面临着…...

T C P

文章目录 基于UDP应用场景 TCP协议TCP 协议段格式确认应答机制16位窗口大小 下定义32位序号和32位确认序号序号是什么&#xff1f;确认序号 基于UDP应用场景 UDP&#xff0c;tcp这样的协议根本不是直接谈UDP。tcp的应用场景&#xff0c;一定是上层写了应用层协议&#xff0c;所…...

MongoDB的简单使用

MongoDB(文档数据库)的简单使用 MongoDB最好的学习资料就是他的官方文档&#xff1a;SQL 到 MongoDB 的映射图表 - MongoDB 手册 v8.0 1.MongoDB CRUD操作 1.1Insert操作 基本方法&#xff1a; db.collection.insertOne() 将单个文档(document)插入集合中 db.collectio…...

【Exp】# Microsoft Visual C++ Redistributable 各版本下载地址

Microsoft官方页面 https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads Redistributable 2019 X86: https://aka.ms/vs/16/release/VC_redist.x86.exe X64: https://aka.ms/vs/16/release/VC_redist.x64.exe Redistributable 201…...

【MySQL】表的约束

目录 一、非空约束not null 二、默认值约束default 三、列描述comment 四、填充零zerofill 五、主键primary key 六、自增长auto_increment 七、唯一键unique 八、外键foreign key 一、非空约束not null 如果不对一个字段做非空约束&#xff0c;则默认为空。但空数据无…...

c++高级篇(四) ——Linux下IO多路复用之epoll模型

IO多路复用 —— epoll 前言 在之前我们就已经介绍过了select和poll,在作为io多路复用的最后一个的epoll,我们来总结一下它们之间的区别: a select 实现原理 select 通过一个文件描述符集合&#xff08;fd_set&#xff09;来工作&#xff0c;该集合可以包含需要监控的文件…...

基于Java Springboot环境保护生活App且微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 微信…...

.NET 9 中 LINQ 新增功能实现过程

本文介绍了.NET 9中LINQ新增功能&#xff0c;包括CountBy、AggregateBy和Index方法,并提供了相关代码示例和输出结果&#xff0c;感兴趣的朋友跟随我一起看看吧 LINQ 介绍 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。 数据查询历来都表示为简单的…...

【Vue3中Router使用】

Vue3中Router使用 1. 安装vue-router组件2. 建两个测试页面2.1 测试页面Home.vue2.2 测试页面Category.vue 3. 创建路由对象4. 在入口main.js中引入router把App.vue改成路由页面5. 测试5.1 关闭检查解决ESlint报错5.2 改文件名解决ESlint检查报错测试WebHashHistory 和WebHisto…...

性能测试攻略(一):需求分析

性能测试成为软件开发和运维过程中不可或缺的一环。性能测试不仅能够帮助我们了解系统在特定条件下的表现&#xff0c;还能帮助我们发现并解决潜在的性能问题。那么我们怎么做一次完整的性能测试呢&#xff1f;首先&#xff0c;我们需要进行需求分析&#xff0c;来明确我们的测…...

android WebRtc 无法推流以及拉流有视频无声音问题

最近在开发使用WebRtc进行视频通话和语音通话&#xff0c;我使用的设备是MTK的手机&#xff0c;期间后台的技术人员几乎没法提供任何帮助&#xff0c;只有接口和测试的web端&#xff0c;有遇到不能推流。推流成功网页端有画面有声音&#xff0c;但是安卓端有画面&#xff0c;没…...

Socket编程TCP

【Linux】TCP编程 实验&#xff1a;通过TCP通信—在客户端输入要执行的指令&#xff0c;接收执行结果&#xff0c;另服务端接收指令并执行&#xff0c;向客户端发送执行结果 //主函数 #include<iostream> #include<string> #include"log.hpp" #include…...

《以 C++为笔,绘就手势识别人机交互新画卷》

在科技浪潮汹涌澎湃的当下&#xff0c;人机交互领域正处于深刻变革的前沿阵地。从古老的命令行输入到图形化界面的鼠标点击&#xff0c;再到如今风靡全球的触摸操控&#xff0c;每一次交互方式的革新都重塑了我们与电子设备的沟通模式。而近年来&#xff0c;手势识别技术作为一…...

【CSS】小球旋转loading加载动画

效果 css小球旋转loading动画 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document<…...

Leetcode经典题6--买卖股票的最佳时机

买卖股票的最佳时机 题目描述&#xff1a; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。…...

BA是什么?

目录 1.EKF的步骤 一、问题定义与模型建立 二、线性化处理 三、应用卡尔曼滤波 四、迭代与收敛 五、结果评估与优化 注意事项 2.BA问题的步骤 一、问题定义与数据准备 二、构建优化模型 三、选择优化算法 四、执行优化过程 五、结果评估与优化 六、应用与验证 1.…...

【IDEA】报错:Try to run Maven import with -U flag (force update snapshots)

问题 IDEA运行项目报错&#xff1a;Try to run Maven import with -U flag (force update snapshots) 原因 IDEA 的项目运行绑定的maven有问题&#xff0c; 解决问题 检查项目绑定的maven配置...

MATLAB提供的窗函数

加窗法 为什么使用加窗法&#xff1f; 在数字滤波器设计和频谱估计中&#xff0c;加窗函数的选择对于整体结果的质量有重大影响。加窗的主要作用是减弱因无穷级数截断而产生的吉布斯现象的影响。 windowDesigner 六种常见的窗函数 根据离散时间傅里叶变换的乘法性质&a…...

git 使用配置

新拿到机器想配置git 获取代码权限&#xff0c;需要的配置方法 1. git 配置用户名和邮箱 git config --global user.name xxxgit config --global user.email xxemail.com 2. 生成ssh key ssh-keygen -t rsa -C "xxemail.com" 3. 获取ssh key cat ~/.ssh/id_rsa.…...

【深度学习】深入解析长短期记忆网络(LSTMs)

长短期记忆网络&#xff08;Long Short-Term Memory networks, LSTMs&#xff09;是一种特殊的递归神经网络&#xff08;RNN&#xff09;&#xff0c;专门设计用来解决标准 RNN 在处理长序列数据时的梯度消失和梯度爆炸问题。LSTMs 在许多序列数据任务中表现出色&#xff0c;如…...

vue watch和computed的区别,computed和method的区别

发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【宝藏入口】。 在 Vue 中&#xff0c;watch、computed 和 methods 都是常用的响应式功能&#xff0c;它们的用途和工作方式有所不同。下面分别解…...

搭建高可用负载均衡系统:Nginx 与云服务的最佳实践

搭建高可用负载均衡系统&#xff1a;Nginx 与云服务的最佳实践 引言 在项目开发过程中&#xff0c;我们通常在开发和测试阶段采用单机架构进行开发和测试。这是因为在这个阶段&#xff0c;系统的主要目的是功能实现和验证&#xff0c;单机架构足以满足开发人员的日常需求&…...

FFmpeg 4.3 音视频-多路H265监控录放C++开发十九,ffmpeg复用

封装就是将 一个h264&#xff0c;和一个aac文件重新封装成一个mp4文件。 这里我们的h264 和 aac都是来源于另一个mp4文件&#xff0c;也就是说&#xff0c;我们会将 in.mp4文件解封装成一路videoavstream 和 一路 audioavstream&#xff0c;然后 将这两路的 avstream 合并成一…...

Node.js JWT认证教程

Node.js JWT认证教程 1. 项目介绍 JSON Web Token (JWT) 是一种安全的跨域身份验证解决方案&#xff0c;在现代Web应用中广泛使用。本教程将详细讲解如何在Node.js中实现JWT认证。 2. 项目准备 2.1 初始化项目 # 创建项目目录 mkdir nodejs-jwt-auth cd nodejs-jwt-auth# …...