串---链串实现
链串详解
本文档将详细介绍链串的基本概念、实现原理及其在 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 君(为了描…...
见证中国数据库的崛起:从追赶到引领的壮丽征程《四》
见证中国数据库的崛起:从追赶到引领的壮丽征程《四》 四、未来展望:中国数据库的机遇与挑战新技术带来的机遇全球化竞争的挑战数据安全与隐私保护的挑战人才培养的持续挑战 【纪录片】中国数据库前世今生 在数字化潮流席卷全球的今天,数据库作…...
OpenCV||超细节的基本操作
一、图像读取 retval cv2.imread(filename[, flags]) filename:需要读取的图片路径名,支持多种图片格式,如JPEG、PNG、TIFF等。flags:一个可选参数,指定加载图像的颜色类型。常用的值包括: cv2.IMGEAD_A…...
算法训练(leetcode)第三十八天 | 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和、392. 判断子序列
刷题记录 *1143. 最长公共子序列1035. 不相交的线53. 最大子数组和392. 判断子序列 *1143. 最长公共子序列 leetcode题目地址 本题和718. 最长重复子数组相似,只是本题不要求连续,需要记录前面最长的子序列,在此基础上累计长度。 dp[i][j]…...
STM32——外部中断(EXTI)
目录 前言 一、外部中断基础知识 二、使用步骤 三、固件库实现 四、STM32CubeMX实现 总结 前言 外部中断(External Interrupt,简称EXTI)是微控制器用于响应外部事件的一种方式,当外部事件发生时(如按键按下、传感器信号…...
MySQL多实例部署
1、软件包下载 //环境:一台rocky Linux虚拟机,并且做好的基本配置及时钟同步,使用Xshell连接 [rootmysql ~]# yum -y install tar lrzsz libncurses* libaio perl//将包文件拖进去 [rootmysql ~]# rz -E rz waiting to receive. [rootmysql…...
云开发喝酒小程序3.6全新漂亮UI猜拳喝酒小程序 【已去除流量主】
云开发喝酒小程序3.6全新漂亮UI猜拳喝酒小程序 已去除流量主。UI特别漂亮,实属精品代码。 【已测】云开发喝酒小程序3.6漂亮UI猜拳喝酒小程序 已去除流量主。 云开发(serverless)小程序无需服务器,注册一个小程序就可以直接上线…...
图论进阶之路-最短路(Floyd)
时间复杂度:O(n^3) 使用场景:当需要得知任意两个点的最短距离以及其路径时使用 准备:需要两个矩阵 一个记录最短距离(D) 一个记录最短路径的最后一个结点(P) 其核心在于不断的判断越过中间…...
安装sqllab靶机之后,练习关卡报403 forbidden
解决办法: 在nginx的conf文件中添加上访问index.php vim /usr/local/nginx/conf/nginx.conf 保存退出 再重启一下nginx,就完成了。 ./nginx -s reload...
微信VX多开 免扫码 登录 互斥体 可视化 Exui v1.1 易语言源码附成品软件
UI设计: 1. EXUI界面库20240204 调用的模块: 1. wow64_hook_3.02.ec(压缩包内含) 2. 精易模块[v11.1.0].ec(自行下载) 更新日志: v1.1 2024年7月25日13:28:43 { 1. 有人反馈 设置了V…...
JavaEE 从入门到精通(一) ~ Maven
晚上好,愿这深深的夜色给你带来安宁,让温馨的夜晚抚平你一天的疲惫,美好的梦想在这个寂静的夜晚悄悄成长。 目录 前言 1.1 概念 什么是 Maven? Maven 的核心概念 1.2 maven依赖坐标 1.3 maven仓库 1.4 maven安装 1.5 mave…...
滚珠丝杆与丝杆支撑座:稳定性与精度的双重保障
丝杆支撑座是连接滚珠丝杆与电机的轴承,采用优质的轴承能确保支撑座与滚珠丝杆之间的刚性平衡。那么,滚珠丝杆搭连接杆支撑座有哪些优缺点呢? 正常情况下,丝杆支撑座能够提供稳定的支撑力,确保滚珠丝杆在复杂工况下保持…...
小男孩与大人做的网站/成人短期技能培训
Spark学习之RDD编程(2) 1. Spark中的RDD是一个不可变的分布式对象集合。 2. 在Spark中数据的操作不外乎创建RDD、转化已有的RDD以及调用RDD操作进行求值。 3. 创建RDD:1)读取一个外部数据集2)在驱动器程序里分发驱动器程序中的对象…...
wordpress首页位置/做一个电商平台大概需要多少钱
java异常 throwable 分为 exception、error error错误 程序无法处理的错误 exception异常 程序本身可以处理的异常 exception 分为 运行时异常、非运行异常 [运行时异常、error] 为 不可检查异常 可不做处理 编译器不做强制 没有异常处理 也能编译通过 [非运行时常] 为…...
成都装修公司一览表/西安seo推广公司
在阅读文章前,您应该具备基本的存储器层次结构知识,至少要了解局部性原理。要详细了解cache基本原理,可以参考本书《深入理解计算机系统》中存储器体系结构一章: 带着疑问来看文章,cache对于程序员是不可见的ÿ…...
学生做资料赚钱网站/贴吧友情链接在哪
大家好,今天呢我给大家分享一下个人独享虚拟桌面是如何创建的,还是之前的环境,这跟以前08R2是有区别的,以前08R2是创建共享虚拟桌面时才需要创建池,而且是手动自己创建,个人虚拟桌面直接指定即可࿱…...
怎么进入网站后台图片/国外免费推广平台有哪些
git操作---跟踪分支设置和预览 从一个远程跟踪分支检出一个本地分支会自动创建所谓的“跟踪分支”。跟踪分支是与远程分支有直接关系的本地分支。 以下有三种方式创建跟踪分支(本地分支): 1、git checkout - b <branch> <remote&…...
手机网站建设哪个/合肥seo网络优化公司
项目一直在使用OrmLite框架,用了这么久,终于有时间做下总结,顺便记录下,方便以后使用 首先说下DataBaseHelper的创建 public class DataBaseHelper extends OrmLiteSqliteOpenHelper {private Dao<UserVO, Integer> mUser…...