串---链串实现
链串详解
本文档将详细介绍链串的基本概念、实现原理及其在 C 语言中的具体应用。通过本指南,读者将了解如何使用链串进行各种字符串操作。
1. 什么是链串?
链串是一种用于存储字符串的数据结构,它使用一组动态分配的节点来保存字符串中的字符序列。链串通常由两部分组成:
- 一个指向链表头结点的指针
s
。 - 一系列的节点,每个节点包含一个字符
data
和指向下一个节点的指针next
。
在本程序中,我们定义了一个名为 LinkStrNode
的结构体来表示链串中的单个节点,并使用一个指针 s
来表示整个链串。
typedef struct StringNode {char data;struct StringNode *next;
} LinkStrNode;
2. 基本操作
2.1 生成串 (StrAssign
)
此函数用于将一个 C 语言字符串转换为链串。
void StrAssign(LinkStrNode *&s, const char str[]) {LinkStrNode *r;LinkStrNode *p;s = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建头结点r = s;for (int i = 0; str[i] != '\0'; i++) {p = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点p->data = str[i]; // 设置数据r->next = p; // 将新节点链接到链表r = p; // 移动指针到新节点}r->next = NULL; // 设置尾节点的 next 为 NULL
}
参数:
s
: 目标链串的头结点指针。str
: 源 C 语言字符串。
功能:
- 为
s
分配一个头结点。 - 为
str
中的每个字符创建一个新的节点,并将其添加到链表中。
2.2 销毁串 (DestroyStr
)
此函数用于释放链串所占用的内存。
void DestroyStr(LinkStrNode *&s) {LinkStrNode *pre = s;LinkStrNode *p = s->next;while (p != NULL) {free(pre); // 释放前一个节点pre = p; // 移动 pre 到当前节点p = pre->next; // 移动 p 到下一个节点}free(pre); // 释放最后一个节点s = NULL; // 清空串指针
}
参数:
s
: 要销毁的链串的头结点指针。
功能:
- 依次释放链串中的每个节点,并清空头结点指针。
2.3 判断是否为空串 (StrEmpty
)
此函数用于检查一个链串是否为空。
bool StrEmpty(LinkStrNode *s){return s->next == NULL;
}
参数:
s
: 要检查的链串的头结点指针。
返回值:
- 如果链串为空(即头结点的
next
指向NULL
),则返回true
;否则返回false
。
2.4 串的复制 (StrCopy
)
此函数用于将一个链串复制到另一个链串。
void StrCopy(LinkStrNode *&s, LinkStrNode *t) {LinkStrNode *p = t->next;LinkStrNode *q;LinkStrNode *r;s = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点r = s;while (p != NULL) {q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULL
}
参数:
s
: 目标链串的头结点指针。t
: 源链串的头结点指针。
功能:
- 为
s
分配一个头结点。 - 复制
t
中的所有节点到s
的链表中。
2.5 判断串相等 (StrEqual
)
此函数用于检查两个链串是否相等。
bool StrEqual(LinkStrNode *s, LinkStrNode *t) {LinkStrNode *p = s->next;LinkStrNode *q = t->next;while (p != NULL && q != NULL && p->data == q->data) {p = p->next;q = q->next;}return (p == NULL && q == NULL);
}
参数:
s
: 第一个链串的头结点指针。t
: 第二个链串的头结点指针。
返回值:
- 如果两个链串具有相同的长度且所有字符都相等,则返回
true
;否则返回false
。
2.6 获得串的长度 (StrLength
)
此函数用于获取一个链串的长度。
int StrLength(LinkStrNode *s) {int i = 0;LinkStrNode *p = s->next;while (p != NULL) {i++;p = p->next;}return i;
}
参数:
s
: 要获取长度的链串的头结点指针。
返回值:
- 返回链串的长度。
2.7 串的连接 (Concat
)
此函数用于将两个链串连接成一个新的链串。
LinkStrNode *Concat(LinkStrNode *s, LinkStrNode *t) {LinkStrNode *str;LinkStrNode *p = s->next;LinkStrNode *q;LinkStrNode *r;str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点r = str;while (p != NULL) {q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}p = t->next;while (p != NULL) {q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULLreturn str;
}
参数:
s
: 第一个链串的头结点指针。t
: 第二个链串的头结点指针。
返回值:
- 返回一个新的链串,该串包含
s
和t
的所有节点。
2.8 获得子串 (SubStr
)
此函数用于从一个链串中获取指定位置的子串。
LinkStrNode *SubStr(LinkStrNode *s, int i, int j) {int k;LinkStrNode *str;LinkStrNode *p = s->next;LinkStrNode *q;LinkStrNode *r;str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点str->next = NULL;r = str;if (i <= 0 || i > StrLength(s) || j < 0 || i + j - 1 > StrLength(s)) {return str;}for (k = 1; k < i; k++) { // 移动到起始位置p = p->next;}for (k = 1; k <= j; k++) { // 复制子串q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULLreturn str;
}
参数:
s
: 原始链串的头结点指针。i
: 子串的起始位置(1-indexed)。j
: 子串的长度。
返回值:
- 返回一个新的链串,该串包含
s
从位置i
开始的长度为j
的子串。
2.9 子串的插入 (InsertStr
)
此函数用于在一个链串的指定位置插入另一个链串。
LinkStrNode *InsertStr(LinkStrNode *s, int i, LinkStrNode *t) {int k;LinkStrNode *str;LinkStrNode *p1 = s->next;LinkStrNode *p2 = t->next;LinkStrNode *q;LinkStrNode *r;str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点str->next = NULL;r = str;if (i <= 0 || i > StrLength(s) + 1) {return str;}for (k = 1; k < i; k++) { // 移动到插入位置q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p1->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p1 = p1->next; // 移动原串指针}while (p2 != NULL) { // 插入子串q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p2->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p2 = p2->next; // 移动原串指针}while (p1 != NULL) { // 继续复制剩余部分q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p1->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p1 = p1->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULLreturn str;
}
参数:
s
: 原始链串的头结点指针。i
: 插入位置(1-indexed)。t
: 要插入的链串的头结点指针。
返回值:
- 返回一个新的链串,该串包含
s
和在位置i
插入的t
。
2.10 子串的删除 (DelStr
)
此函数用于从一个链串中删除指定位置的子串。
LinkStrNode *DelStr(LinkStrNode *s, int i, int j) {int k;LinkStrNode *str;LinkStrNode *p = s->next;LinkStrNode *q;LinkStrNode *r;str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点str->next = NULL;r = str;if (i <= 0 || i > StrLength(s) || j < 0 || i + j - 1 > StrLength(s)) {return str;}for (k = 1; k < i; k++) { // 移动到删除位置前q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}for (k = 0; k < j; k++) { // 跳过要删除的部分p = p->next; // 移动原串指针}while (p != NULL) { // 复制剩余部分q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULLreturn str;
}
参数:
s
: 原始链串的头结点指针。i
: 子串的起始位置(1-indexed)。j
: 子串的长度。
返回值:
- 返回一个新的链串,该串包含
s
除位置i
开始的长度为j
的子串外的所有节点。
2.11 子串的替换 (ReplaceSubStr
)
此函数用于在一个链串的指定位置替换一个子串。
LinkStrNode *ReplaceSubStr(LinkStrNode *s, int i, int j, LinkStrNode *t) {LinkStrNode *newStr = InsertStr(s, i, t); // 先执行插入操作LinkStrNode *delStr = DelStr(newStr, i, j); // 再执行删除操作DestroyStr(newStr); // 销毁中间串return delStr; // 返回替换后的串
}
参数:
s
: 原始链串的头结点指针。i
: 要替换子串的起始位置(1-indexed)。j
: 要替换子串的长度。t
: 新的子串的头结点指针。
返回值:
- 返回一个新的链串,该串包含
s
除位置i
开始的长度为j
的子串被t
替换外的所有节点。
2.12 串的比较 (StrCompare
)
此函数用于比较两个链串。
int StrCompare(LinkStrNode *s, LinkStrNode *t) {LinkStrNode *p = s->next, *q = t->next;while (p != NULL && q != NULL) {if (p->data != q->data) {return p->data > q->data ? 1 : -1;}p = p->next;q = q->next;}if (p == NULL && q == NULL) {return 0;} else if (p == NULL) {return -1;} else {return 1;}
}
参数:
s
: 第一个链串的头结点指针。t
: 第二个链串的头结点指针。
返回值:
- 如果
s
和t
相等,返回 0; - 如果
s
小于t
,返回负数; - 如果
s
大于t
,返回正数。
2.13 打印链串 (PrintStr
)
此函数用于显示一个链串的内容。
void PrintStr(LinkStrNode *s) {LinkStrNode *p = s->next;while (p != NULL) {printf("%c", p->data);p = p->next;}printf("\n");
}
参数:
s
: 要显示的链串的头结点指针。
3. 示例程序
下面是一个示例程序,演示了如何使用上述定义的功能。
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // 用于使用 strlen 函数
#define MaxSize 100// 链串的结构体
typedef struct StringNode {char data;struct StringNode *next;
} LinkStrNode;// 生成串
void StrAssign(LinkStrNode *&s, const char str[]) {LinkStrNode *r;LinkStrNode *p;s = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建头结点r = s;for (int i = 0; str[i] != '\0'; i++) {p = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点p->data = str[i]; // 设置数据r->next = p; // 将新节点链接到链表r = p; // 移动指针到新节点}r->next = NULL; // 设置尾节点的 next 为 NULL
}// 销毁串
void DestroyStr(LinkStrNode *&s) {LinkStrNode *pre = s;LinkStrNode *p = s->next;while (p != NULL) {free(pre); // 释放前一个节点pre = p; // 移动 pre 到当前节点p = pre->next; // 移动 p 到下一个节点}free(pre); // 释放最后一个节点s = NULL; // 清空串指针
}//判断是否为空串
bool StrEmpty(LinkStrNode *s){return s->next == NULL;
} // 串的复制
void StrCopy(LinkStrNode *&s, LinkStrNode *t) {LinkStrNode *p = t->next;LinkStrNode *q;LinkStrNode *r;s = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点r = s;while (p != NULL) {q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULL
}// 判断串相等
bool StrEqual(LinkStrNode *s, LinkStrNode *t) {LinkStrNode *p = s->next;LinkStrNode *q = t->next;while (p != NULL && q != NULL && p->data == q->data) {p = p->next;q = q->next;}return (p == NULL && q == NULL);
}// 获得串的长度
int StrLength(LinkStrNode *s) {int i = 0;LinkStrNode *p = s->next;while (p != NULL) {i++;p = p->next;}return i;
}// 串的连接
LinkStrNode *Concat(LinkStrNode *s, LinkStrNode *t) {LinkStrNode *str;LinkStrNode *p = s->next;LinkStrNode *q;LinkStrNode *r;str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点r = str;while (p != NULL) {q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}p = t->next;while (p != NULL) {q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULLreturn str;
}// 获得子串
LinkStrNode *SubStr(LinkStrNode *s, int i, int j) {int k;LinkStrNode *str;LinkStrNode *p = s->next;LinkStrNode *q;LinkStrNode *r;str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点str->next = NULL;r = str;if (i <= 0 || i > StrLength(s) || j < 0 || i + j - 1 > StrLength(s)) {return str;}for (k = 1; k < i; k++) { // 移动到起始位置p = p->next;}for (k = 1; k <= j; k++) { // 复制子串q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULLreturn str;
}// 子串的插入
LinkStrNode *InsertStr(LinkStrNode *s, int i, LinkStrNode *t) {int k;LinkStrNode *str;LinkStrNode *p1 = s->next;LinkStrNode *p2 = t->next;LinkStrNode *q;LinkStrNode *r;str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点str->next = NULL;r = str;if (i <= 0 || i > StrLength(s) + 1) {return str;}for (k = 1; k < i; k++) { // 移动到插入位置q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p1->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p1 = p1->next; // 移动原串指针}while (p2 != NULL) { // 插入子串q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p2->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p2 = p2->next; // 移动原串指针}while (p1 != NULL) { // 继续复制剩余部分q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p1->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p1 = p1->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULLreturn str;
}// 子串的删除
LinkStrNode *DelStr(LinkStrNode *s, int i, int j) {int k;LinkStrNode *str;LinkStrNode *p = s->next;LinkStrNode *q;LinkStrNode *r;str = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 创建新的头结点str->next = NULL;r = str;if (i <= 0 || i > StrLength(s) || j < 0 || i + j - 1 > StrLength(s)) {return str;}for (k = 1; k < i; k++) { // 移动到删除位置前q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}for (k = 0; k < j; k++) { // 跳过要删除的部分p = p->next; // 移动原串指针}while (p != NULL) { // 复制剩余部分q = (LinkStrNode *)malloc(sizeof(LinkStrNode)); // 分配新节点q->data = p->data; // 设置数据r->next = q; // 将新节点链接到链表r = q; // 移动指针到新节点p = p->next; // 移动原串指针}r->next = NULL; // 设置尾节点的 next 为 NULLreturn str;
}// 子串的替换
LinkStrNode *ReplaceSubStr(LinkStrNode *s, int i, int j, LinkStrNode *t) {LinkStrNode *newStr = InsertStr(s, i, t); // 先执行插入操作LinkStrNode *delStr = DelStr(newStr, i, j); // 再执行删除操作DestroyStr(newStr); // 销毁中间串return delStr; // 返回替换后的串
}int StrCompare(LinkStrNode *s, LinkStrNode *t) {LinkStrNode *p = s->next, *q = t->next;while (p != NULL && q != NULL) {if (p->data != q->data) {return p->data > q->data ? 1 : -1;}p = p->next;q = q->next;}if (p == NULL && q == NULL) {return 0;} else if (p == NULL) {return -1;} else {return 1;}
}// 打印链串
void PrintStr(LinkStrNode *s) {LinkStrNode *p = s->next;while (p != NULL) {printf("%c", p->data);p = p->next;}printf("\n");
}// 主函数
int main() {LinkStrNode *s, *t;char input[MaxSize];// 用户输入第一个串printf("请输入第一个字符串: ");scanf("%s", input);StrAssign(s, input);// 用户输入第二个串printf("请输入第二个字符串: ");scanf("%s", input);StrAssign(t, input);// 显示两个串printf("第一个字符串: ");PrintStr(s);printf("第二个字符串: ");PrintStr(t);// 检查是否为空串if (StrEmpty(s)) {printf("第一个串为空串。\n");} else {printf("第一个串不为空串。\n");}if (StrEmpty(t)) {printf("第二个串为空串。\n");} else {printf("第二个串不为空串。\n");}// 比较两个串int result = StrCompare(s, t);if (result == 0) {printf("两个串相等。\n");} else if (result < 0) {printf("第一个串小于第二个串。\n");} else {printf("第一个串大于第二个串。\n");}// 计算两个串的长度printf("第一个串的长度为: %d\n", StrLength(s));printf("第二个串的长度为: %d\n", StrLength(t));// 连接两个串LinkStrNode *concatenated = Concat(s, t);printf("连接后的字符串: ");PrintStr(concatenated);// 获取子串int start, length;printf("请输入子串起始位置 (1-%d): ", StrLength(s));scanf("%d", &start);printf("请输入子串长度: ");scanf("%d", &length);LinkStrNode *substring = SubStr(s, start, length);printf("子串为: ");PrintStr(substring);// 插入子串printf("请输入插入位置 (1-%d): ", StrLength(s) + 1);scanf("%d", &start);LinkStrNode *inserted = InsertStr(s, start,t );printf("插入后的字符串: ");PrintStr(inserted);// 删除子串printf("请输入删除起始位置 (1-%d): ", StrLength(s));scanf("%d", &start);printf("请输入删除长度: ");scanf("%d", &length);LinkStrNode *deleted = DelStr(s, start, length);printf("删除后的字符串: ");PrintStr(deleted);// 替换子串printf("请输入替换起始位置 (1-%d): ", StrLength(s));scanf("%d", &start);printf("请输入替换长度: ");scanf("%d", &length);LinkStrNode *replaced = ReplaceSubStr(s, start, length, t);printf("替换后的字符串: ");PrintStr(replaced);return 0;
}
4. 使用说明
- 编译并运行上述示例程序。
- 根据提示输入两个字符串。
- 观察并理解各个操作的结果。
5. 总结
通过本文档,您可以了解到链串的基本概念和常用操作。使用这些操作,您可以轻松地处理字符串数据,进行各种字符串相关的任务。希望这份指南能够帮助您更好地理解和使用链串。
相关文章:
串---链串实现
链串详解 本文档将详细介绍链串的基本概念、实现原理及其在 C 语言中的具体应用。通过本指南,读者将了解如何使用链串进行各种字符串操作。 1. 什么是链串? 链串是一种用于存储字符串的数据结构,它使用一组动态分配的节点来保存字符串中的…...

科技赋能生活——便携气象站
传统气象站往往庞大而复杂,需要专业人员维护,它小巧玲珑,设计精致,可以轻松放入背包或口袋,随身携带,不占空间。无论是城市白领穿梭于高楼大厦间,还是户外爱好者深入山林湖海,都能随…...
Golang——GC原理
1.垃圾回收的目的 将未被引用到的对象销毁,回收其所占的内存空间。 2.根对象是什么 全局变量:在编译器就能确定的存在于程序整个生命周期的变量。 执行栈:每个goroutine都包含自己的执行栈,这些执行栈上包含栈上的变量及指向分配…...

OpenStack概述
一、初识OpenStack OpenStack Docs: 概况 一)OpenStack架构简述 1、理解OpenStack OpenStack既是一个社区,也是一个项目和一个开源软件,提供开放源码软件,建立公共和私有云,它提供了一个部署云的操作平台或工具集&…...

机器学习练手(三):基于决策树的iris 多分类和波士顿房价预测
总结:本文为和鲸python 可视化探索训练营资料整理而来,加入了自己的理解(by GPT4o) 原活动链接 原作者:vgbhfive,多年风控引擎研发及金融模型开发经验,现任某公司风控研发工程师,对…...

PS 2024 百种常用插件下载安装教程【免费使用,先到先得】
文章目录 软件介绍软件下载安装步骤 专栏推荐: 超多精品软件(持续更新中…) 软件推荐: PS 2024 PR 2024 软件介绍 PS常用插件 此软件整合了市面近百款ps处理插件,可实现:一键制作背景,一键抠图…...

逻辑推理之lora微调
逻辑推理微调 比赛介绍准备内容lora微调lora微调介绍lora优势代码内容 start_vllm相关介绍调用 运行主函数提交结果总结相应连接 比赛介绍 本比赛旨在测试参与者的逻辑推理和问题解决能力。参与者将面对一系列复杂的逻辑谜题,涵盖多个领域的推理挑战。 比赛的连接:…...
前端-防抖代码
//防抖debounce(fn, time 1000) {let timer null;return function (...args) {if (timer) clearTimeout(timer);timer setTimeout(() > {fn.apply(this, args);}, time);};},// 输入变化处理函数async inputChange(value) {if (!this.debouncedInputChange) {this.deboun…...
langchain 入门指南 - 让 LLM 自动选择不同的 Prompt
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 让 LLM 自动选择不同的 Prompt 在上一篇文章中,我们学会了如何让 langchain 来自动选择不同的 LLM Chain,以便回…...

web浏览器播放rtsp视频流,海康监控API
概述 这里记录一下如何让前端播放rtsp协议的视频流 项目中调用海康API,生成的视频流(hls、ws、rtmp等)通过PotPlayer播放器都无法播放,说明视频流有问题,唯独rtsp视频流可以播放。 但是浏览器本身是无法播放rtsp视频的,即使…...

操作系统原理:程序、进程、线程的概念
文章目录 程序、进程、线程的概念程序(Program)进程(Process)线程(Thread)关系总结 在日常对操作系统的使用中,大家肯定对程序、进程和线程多少有所耳闻。作为操作系统的重要一部分,…...

Golang是如何实现动态数组功能的?Slice切片原理解析
Hi 亲爱的朋友们,我是 k 哥。今天,咱们聊一聊Golang 切片。 当我们需要使用数组,但是又不能提前定义数组大小时,可以使用golang的动态数组结构,slice切片。在 Go 语言的众多特性里,slice 是我们经常用到的数…...

SQL注入 报错注入+附加拓展知识,一篇文章带你轻松入门
第5关--------------------------------------------> 前端直接不会显示账号密码的打印;但是在接收前端的数据的那部分后端那里,会看前端传递过来的值是否正确,如果不正确,后端接收值那里就会当MySQL语句执行错误,…...
springboot项目里的包spring-boot-dependencies依赖介绍
springboot项目里的包’spring-boot-dependencies‘依赖 我们一般是在项目的pom dependencyManagement标签里引入spring-boot-dependencies,或者根spring-boot-starter-parent里也是继承了它,也正是因为继承了这个依赖,所以我们在写依赖时才不需要写版本…...

C# 下的限定符运算详解(全部,任意,包含)与示例
文章目录 1.限定符概述2. 全部限定符运算(All)3. 任意限定符运算(Any)4. 包含限定符运算(Contains)总结 当我们在C#编程中需要进行条件判断或集合操作时,限定符(qualifiersÿ…...
消息队列RabbitMQ部分知识
1.简述RabbitMQ的架构设计 RabbitMQ 是一个开源的消息代理,采用了高级消息队列协议(AMQP),其架构设计主要包括以下几个关键组件和概念: 1.消息生产者( Producer): 负责发送消息到…...

看门狗应用编程-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板
看门狗应用编程 看门狗应用编程介绍 看门狗定时器的基本概念 看门狗是一个可以在一定时间内被复位/重置的计数器 如果在规定时间内没有复位,看门狗计时器溢出会对CPU产生复位信号使系统重启 有些看门狗可以只产生中断信号而不会使系统复位 I.MX6UL/I.MX6ULL So…...

Bug 解决 | 本地项目上线后出现错误
目录 一、前言 二、原因分析 1、本地代码误发线上 2、环境差异 3、配置差异 4、资源路径差异 5、API 接口差异 6、用量差异 一、前言 大家好,我是小洪爱分享。在开发上线项目的过程中,我们经常会遇到一种让人头疼的情况。那就是开发好的项目功能…...

为什么我工作 10 年后转行当程序员?逆袭翻盘!
今天文章的主人公暂且称他为 A 君。不过 A 君有点特别,非科班,工作 10 年后才转行 iOS 程序员。今年 36 岁,目前在某行业头部企业任职前端负责人,管理 40 人的前端团队。 废话不多说,我们开始 A 君(为了描…...

见证中国数据库的崛起:从追赶到引领的壮丽征程《四》
见证中国数据库的崛起:从追赶到引领的壮丽征程《四》 四、未来展望:中国数据库的机遇与挑战新技术带来的机遇全球化竞争的挑战数据安全与隐私保护的挑战人才培养的持续挑战 【纪录片】中国数据库前世今生 在数字化潮流席卷全球的今天,数据库作…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

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

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...