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

数据结构篇:线性表的另一表达—链表之单链表(下篇)

目录

1.前言

2.是否使用二级指针

3.插入/删除

        3.1 pos位置前/后插入

3.2 查找函数

3.3 pos位置删除

3.4 pos位置后面删除

3.5 函数的销毁 

4.断言问题

        4.1 断言pphead

        4.2 断言*pphead

5.三个文件的代码 

5.1 头文件

5.2 具体函数实现

5.3 测试用例


1.前言

        之前是讲述了单链表的头插尾插,头删尾删函数部分,并且揭示了链表相对于顺序表的优势性。更重要的是对于next的理解和对二级指针的理解,为什么在单链表中用一级指针报错而要用二级指针,其实简单的说就是看会不会改变指针指向

2.是否使用二级指针

        在单链表中,无论是尾插还是尾删。尾插的时候,在第一次插入元素的时候,没有节点,头节点是一个指向为空。实参那里一开始的链表初始化为空,是一个NULL。要尾插的时候,通过函数来改变外部的这个phead的指向,这个实参plist是一个一级指针,如果要通过函数来改变这个一级指针的指向,就是要传二级指针,也就是一级指针的地址

        头插的时候,传的是二级指针,因为和尾插一样,每次头插都要改变头节点的指向。

        尾删的时候,删到最后一个节点,它就会改变头节点的指向,仔细想,删除最后一个节点删没了,头节点这个时候指向应该指向空,所以也是要二级指针才能改变。


        结论就是看这个头节点会不会变,如果会变的话,就用二级指针,如果不变,那就不用传二级指针。

3.插入/删除

        3.1 pos位置前/后插入

        和顺序表一样 ,链表也是可以在中间某个位置pos前/后插入的,而且在特殊位置,比如在第一个位置前插入,那等同于头插。那么就可以把头插的函数复用就可以了。思路是:定义一个前指针这里用former,找到pos的前一个位置,怎么找呢,有next这个节点,只要former的next不是pos的地址,就一直遍历,直至找到。然后former的next指向新节点,新节点的next再指向pos。(相当于把former和pos之间的指针断开了,重新进行了指向),这是pos位置前插入的思路图:

pos位置前插入

测试用例如下:找到3的位置,然后在3的位置前插入7

测试用例

         当然也可以有头插的效果,在判断该位置是否是头节点后,如果是,就复用头插函数

void SLTinsert(SLTnode** pphead,SLTnode*pos, Sltdatatype x)
{assert(pos);assert(pphead);//如果pos是第一个,就等于头插if (pos == *pphead){//复用头插函数SLTpushfront(pphead,x);}
}

        测试当然也是成功的:

        pos位置后面插入,也是同理,先查找,是否有该位置存在,有就给出一个返回值。然后进行插入,那么既然在第一个位置前插入数据等同于头插,那在最后一个位置后插入,是什么,应该是尾插吧。

        思路就是找到pos后,先用一个next的指针保存原来pos的next,然后pos的next指向newnode,也就是新节点,最后新节点的next再指向保存原来pos的next的那个next指针。有点小绕,但画个图就明白了。保存是为了更方便点。这是顺序的从左到右依次连接。

        或者不那么绕,前者是pos->newnode->pos的下一个,形成了中间插入。也可以newnode->posd的next,pos->newnode。从后往前连接,就可以不用定义指针去保存pos的下一个节点。代码会少一两行。这里我选用第二种方法

void SLTinsert_afterpos(SLTnode** pphead,SLTnode *pos, Sltdatatype x)
{assert(pphead);assert(pos);SLTnode* newnode = insertSLTnode(x);newnode->next = pos->next;pos->next = newnode;
}

3.2 查找函数

        在上文中,我们要在pos位置插入,和顺序表一样,也是需要先找到该位置才能进行插入,需要有个返回值,然后再调用插入函数。而查找函数思路也很简单,只需要遍历链表,找到是否有data等于x的值就可以,没有就返回NULL。

SLTnode* SLTfind(SLTnode* pphead, Sltdatatype x)
{//遍历SLTnode* cur = pphead;while (cur){if (cur->data==x){return cur;}cur = cur->next;}return NULL;
}

3.3 pos位置删除

        经过pos位置的前后插入练习,其实pos位置的删除,pos位置后的删除思路也是很明确了。正确掌握好链表的位置关系,以及对next的理解,就基本没什么问题。删除pos位置,也就是意味着要把pos的前后连起来,并且释放掉pos位置。那么就需要有一个former指针,该指针的next指向pos的next,就可以了。思路图如下:

        特殊情况:如果要删除的位置是头节点,也就是头删,同样复用头删函数。

void SLTErase(SLTnode** pphead, SLTnode* pos)
{assert(pphead);assert(*pphead);if (pos == *pphead){SLTpopfront(pphead);}else{SLTnode* former = *pphead;while (former->next != pos){former = former->next;}former->next = pos->next;free(pos);}
}

3.4 pos位置后面删除

        紧接着来看pos位置后删除,这里同pos位置后插入一样,有两种写法,一种是pos的next指向pos的next的next,就是跳过了中间的数据,因为中间的数据是要被删除的。最后释放掉pos后面的位置就行。


或者用一个有意义的名字定义个指针,该指针把要删除的数据保存下来,pos的next和该指针的下一个连接起来就可以。两者其实没有本质区别的。 

void SLTerase_afterpos(SLTnode** pphead, SLTnode* pos)
{assert(pos->next);SLTnode* erase = pos->next;pos->next = pos->next->next;free(erase);erase = NULL;}

 之前的案例是在3的后面插入一个7,那么这次把7删掉,就是可以用到pos后面删除数据。

3.5 函数的销毁 

        由于我们申请的空间都是malloc出来,在堆上申请的,那根据malloc的特质,我们需要需要把它销毁掉并且置空,防止内存泄露的问题出现。

        销毁的思路就是,把链表存放到一个指针中(cur)(这里不需要改变指针的指向,只是改变结构体的内容,所以只需要一级指针),用另一个指针next去保存当前节点的下一个,先释放保存链表数据的cur指针,然后指针内容更新为节点的下一个,循环到链表为空。这里没有进行置空,是因为函数的形参不改变实参,所以里面置空不影响外部函数链表的结果,一级指针改变不了一级指针的内容,如果要在里面更改就要传递二级指针。所以我传的是一级指针,在外部置空。

void SLTdestory(SLTnode * phead)
{SLTnode* cur = phead;while (cur){SLTnode* next = cur->next;free(cur);cur=next;}
}

4.断言问题

        在写单链表的过程中,每个函数是否要断言,断言哪些地方,是需要考虑的,不能一刀切,结合实际情况实际考虑的

        4.1 断言pphead

        首先断言的情况是pphead传入的是链表地址,链表的地址传错了的话是NULL会发生报错,那么我们要断言的情况,就是防止有空的误传进来(比如没有取地址)。所以链表地址一定不为空。

        4.2 断言*pphead

        *pphead,是链表的内容,看*pphead有没有可能为空,如果这个值在某个情况下不应该是空,那么我们就可以断言,因为不可能为空的,一定有数值的传进来,结果你断言后报错了,说明传进来的有问题啊。如果这个函数允许有空的存在,那么不需要断言,因为断言了不就传不进来,就与初衷有悖。


        举个例子,插入的时候,*pphead有没有可能为空,空链表能插入,说明可以为空,为空你加assert(*pphead),那不是铁铁报错吗。空链表能打印,能插入,不用断言空链表不能尾删,不能头删,要断言,为空还删什么。但是pphead要断言,它是链表的地址,它一定铁定不为空。所以一定要*pphead断言

        结论是:  所以有个思维就是如果这个值绝对不为空,那么我们就可以断言。而且断言会直接报错,告诉你错在哪里,根据场景去灵活变通,发现基本错误,调试的成本,花费的时间要远比断言来的高。在这里pphead一定不为空,*pphead看场景。具体情况具体分析。

5.三个文件的代码 

        这里展示头文件,具体函数和测试用例的全部代码。

5.1 头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int Sltdatatype;
typedef struct SListnode
{Sltdatatype data;struct SListnode* next;
}SLTnode;
void SLTprint(SLTnode *phead);
SLTnode* insertSLTnode(Sltdatatype x);
void SLTpushback(SLTnode** pphead, Sltdatatype x);
void SLTpopback(SLTnode** pphead);
void SLTpushfront(SLTnode** pphead, Sltdatatype x);
void SLTpopfront(SLTnode** pphead);
SLTnode* SLTfind(SLTnode* pphead, Sltdatatype x);
//pos之前插入
void SLTinsert(SLTnode **pphead,SLTnode*pos,Sltdatatype x);
//pos位置删除
void SLTErase(SLTnode** pphead, SLTnode* pos);
//pos后面插入
void SLTinsert_afterpos(SLTnode**phead,SLTnode* pos,Sltdatatype x);
//pos后面删除
void SLTerase_afterpos(SLTnode** pphead, SLTnode* pos);
//链表销毁
void SLTdestory(plist);

5.2 具体函数实现

#define _CRT_SECURE_NO_WARNINGS 1
#include"Slist.h"
SLTnode* insertSLTnode(Sltdatatype x)
{//申请一块空间给新的节点SLTnode* newnode = (SLTnode*)malloc(sizeof(SLTnode));if (newnode == NULL){perror("fail malloc");return 0;}newnode->data = x;newnode->next = NULL;return newnode;
}
//尾插
void SLTpushback(SLTnode **pphead,Sltdatatype x)
{assert(pphead);SLTnode* newnode = insertSLTnode(x);if (*pphead==NULL){*pphead = newnode;}//找尾else{//定义尾变量SLTnode* tail = *pphead;while (tail->next!=NULL){tail = tail->next;}//tail->next这个指针指向新节点tail->next= newnode;}
}//尾删
void SLTpopback(SLTnode** pphead)
{//检查assert(pphead);assert(*pphead);//一个节点if ((*pphead)->next==NULL){free(*pphead);*pphead = NULL;}//多个节点else{// 找尾SLTnode* former = NULL;SLTnode* tail = *pphead;while (tail->next != NULL){former = tail;tail = tail->next;}free(tail);tail = NULL;former->next = NULL;}
}
void SLTprint(SLTnode* phead)
{SLTnode* cur = phead;while (cur){printf("%d ",cur->data);cur=cur->next;}printf("NULL\n");
}//头插
void SLTpushfront(SLTnode** pphead, Sltdatatype x)
{assert(pphead);SLTnode* newnode = insertSLTnode(x);//把newnode的下一个给pilstnewnode->next = *pphead;//链表指针指向新节点,变成新的头部*pphead =newnode;
}
//头删
void SLTpopfront(SLTnode** pphead)
{assert(pphead);assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}//第一个节点的地址,给到first这个指针SLTnode* first = *pphead;//plist指向first的下一个地址,就是第二个节点*pphead = first->next;free(first);//删除第一个first = NULL;
}
SLTnode* SLTfind(SLTnode* pphead, Sltdatatype x)
{//遍历SLTnode* cur = pphead;while (cur){if (cur->data==x){return cur;}cur = cur->next;}return NULL;
}
void SLTinsert(SLTnode** pphead,SLTnode*pos, Sltdatatype x)
{assert(pos);assert(pphead);//如果pos是第一个,就等于头插if (pos == *pphead){//复用头插函数SLTpushfront(pphead,x);}else{SLTnode* former = *pphead;if (former->next!=pos){former = former->next;}SLTnode* newnode = insertSLTnode(x);former->next = newnode;newnode->next = pos;}
}
void SLTErase(SLTnode** pphead, SLTnode* pos)
{assert(pphead);assert(*pphead);if (pos == *pphead){SLTpopfront(pphead);}else{SLTnode* former = *pphead;while (former->next != pos){former = former->next;}former->next = pos->next;free(pos);}}
void SLTinsert_afterpos(SLTnode** pphead,SLTnode *pos, Sltdatatype x)
{assert(pphead);assert(pos);SLTnode* newnode = insertSLTnode(x);newnode->next = pos->next;pos->next = newnode;
}void SLTerase_afterpos(SLTnode** pphead, SLTnode* pos)
{assert(pos->next);SLTnode* erase = pos->next;
pos->next = pos->next->next;free(erase);erase = NULL;}void SLTdestory(SLTnode * phead)
{SLTnode* cur = phead;while (cur){SLTnode* next = cur->next;free(cur);cur=next;}
}

5.3 测试用例


void test7()
{SLTnode* plist = NULL;SLTpushback(&plist, 1);SLTpushback(&plist, 2);SLTpushback(&plist, 3);SLTpushback(&plist, 4);SLTpushback(&plist, 5);SLTprint(plist);SLTnode* ret = SLTfind(plist, 3);SLTinsert_afterpos(&plist,ret,7);SLTprint(plist);SLTerase_afterpos(&plist, ret);SLTprint(plist);SLTdestory(plist);plist = NULL;
}
int main()
{test7();return 0;
}

        单链表的复习和讲解就到这里了 ,单链表一开始学习还是比较晦涩难懂的,但是写多了,错误多了,坑踩多了,就会熟悉里面的内容了。还是要多理解,多做题,后面也会讲解一些单链表的O经典J题来加强印象。多做题也是熟悉链表的一个很好的方式!

相关文章:

数据结构篇:线性表的另一表达—链表之单链表(下篇)

目录 1.前言 2.是否使用二级指针 3.插入/删除 3.1 pos位置前/后插入 3.2 查找函数 3.3 pos位置删除 3.4 pos位置后面删除 3.5 函数的销毁 4.断言问题 4.1 断言pphead 4.2 断言*pphead 5.三个文件的代码 5.1 头文件 5.2 具体函数实现 5.3 测试用例 1.前言 之前是讲…...

C# 异步详解

C# 异步编程详解 一、异步编程基础概念 1. 同步 vs 异步 ​​同步(Synchronous)​​&#xff1a;任务按顺序执行&#xff0c;前一个任务完成后才会执行下一个​​异步(Asynchronous)​​&#xff1a;任务可以非阻塞地启动&#xff0c;主线程可以继续执行其他操作 2. 异步编…...

X²+1素数问题

X1素数问题是与哥德巴赫猜想和孪生素数猜想同时代的著名数学难题。是否有无穷个正整数x&#xff0c;使得x1总是素数&#xff1f; 其困难程度不亚于哥德巴赫猜想。特别是100多年以来&#xff0c;许许多多一流数论学者对这个问题进行了研究。 X1素数 X1素数是一个著名的猜想&…...

【自定义控件实现最大高度和最大宽度实现】

背景 开发中偶尔遇到控件宽度或者高度在自适应的情况下&#xff0c;有个边界值&#xff0c;也就是最大值。 比如高度自适应的情况下最大高度300dp这种场景。 实现 关键节点代码&#xff1a; Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)…...

基于C++的IOT网关和平台4:github项目ctGateway交互协议

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。 源码指引:github源码指引_初级代码游戏的博客-CSDN博客 …...

DeepSeek谈《凤凰项目 一个IT运维的传奇故事》

《凤凰项目&#xff1a;一个IT运维的传奇故事》&#xff08;The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win&#xff09;是Gene Kim、Kevin Behr和George Spafford合著的一部小说&#xff0c;通过虚构的故事生动展现了IT运维中的核心挑战和Dev…...

Spyglass:官方Hands-on Training(一)

相关阅读 Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828934.html?spm1001.2014.3001.5482 本文是对Spyglass Hands-on Training中第一个实验的翻译&#xff08;有删改&#xff09;&#xff0c;Lab文件可以从以下链接获取。Spyglass Hands-on Traininghttps:…...

10.idea中创建springboot项目_jdk17

10.idea中创建springboot项目_jdk17 1. 准备工作 安装 JDK 17&#xff1a; 确保已安装 JDK 17&#xff0c;并配置环境变量 JAVA_HOME 指向 JDK 17 的安装路径。在 IntelliJ IDEA 中验证 JDK 配置&#xff1a;File → Project Structure → SDKs。 安装 IntelliJ IDEA&#x…...

指令级并行(ILP)和线程级并行(TLP)的区别,GCC -O3优化会展开循环吗?

1. GCC 自动循环展开是怎么展开的&#xff1f; 当你使用 -O3 这样的优化选项时&#xff0c;GCC 会分析你的循环。如果它认为展开循环有利可图&#xff0c;它会做类似这样的事情&#xff08;概念上的&#xff09;&#xff1a; 原始循环 (Conceptual C Code): for (int i 0; i …...

hadoop伪分布式模式

以下是 Hadoop 伪分布式模式&#xff08;Pseudo-Distributed Mode&#xff09;的环境搭建步骤。伪分布式模式下&#xff0c;Hadoop 的各个组件&#xff08;如 HDFS、YARN、MapReduce&#xff09;以独立进程运行&#xff0c;但所有服务均部署在单台机器上&#xff0c;模拟多节点…...

C++入门小馆: 模板

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…...

# 基于 Python 和 jieba 的中文文本自动摘要工具

基于 Python 和 jieba 的中文文本自动摘要工具 在信息爆炸的时代&#xff0c;快速准确地提取文本核心内容变得至关重要。今天&#xff0c;我将介绍一个基于 Python 和 jieba 的中文文本自动摘要工具&#xff0c;帮助你高效地从长文本中提取关键信息。 一、背景与需求 在处理…...

.NET平台用C#在PDF中创建可交互的表单域(Form Field)

在日常办公系统开发中&#xff0c;涉及 PDF 处理相关的开发时&#xff0c;生成可填写的 PDF 表单是一种常见需求&#xff0c;例如员工信息登记表、用户注册表、问卷调查或协议确认页等。与静态 PDF 不同&#xff0c;带有**表单域&#xff08;Form Field&#xff09;**的文档支持…...

Azure AI Foundry实战:从零开始构建智能应用

1. 引言 在人工智能快速发展的今天,如何高效地开发和部署AI应用已成为众多开发者和企业关注的焦点。微软的Azure AI Foundry应运而生,为AI应用开发提供了一站式解决方案。本文将带您深入了解Azure AI Foundry,并通过实战指南,帮助您从零开始构建智能应用。 2. Azure AI Found…...

YOLO视觉模型可视化训练与推理测试工具

推荐一款YOLO可视化训练测试工具: 对于yolo的训练,新手小白往往无从下手,本章推荐的这款工具可以非常轻易的帮您从模型训练到测试到部署。 下载地址http://www.voouer.com/yolo 可以点击此处跳转。 下载成功后打开这款工具,将会出现图形化界面,类似于下图所示: 当前页是可视…...

数据清洗的定义跟实际操作

数据清洗的定义 数据清洗&#xff08;Data Cleaning&#xff09; 是指对原始数据进行处理&#xff0c;以纠正、删除或填补不完整、不准确、重复或无关的数据&#xff0c;使其符合分析或建模的要求。数据清洗是数据预处理的关键步骤&#xff0c;直接影响后续分析和机器学习模型…...

如何用AI生成个人职业照/西装照?

一、核心工具推荐与对比 1. 搜狐简单AI • 特点&#xff1a; • 一键生成&#xff1a;上传1张生活照&#xff0c;AI自动生成职业照/西装照&#xff0c;支持商务精英、韩系女主等20模板。 • 自然微调&#xff1a;优化五官比例、柔化法令纹&#xff0c;保留个人特色&#xff0…...

Ecology中拦截jquery.ajax请求接口后的数据

功能&#xff1a;获取调用接口之后的数据在进行返回参数重写 首先ecology中一般直接看不到源码的&#xff0c;为什么知道是jquery.ajax请求呢&#xff0c;需要用到开发者工具 点开这里之后就能知道调用接口具体走的是什么逻辑然后返回值又做了哪些操作 一般来说&#xff0c;文…...

基于站点观测的中国1km土壤湿度日尺度数据集(2000-2022)

A 1 km daily soil moisture dataset over China based on in-situ measurement (2000-2022) 关键数据集分类地表参数数据集时间分辨率日空间分辨率1km - 10km共享方式开放获取数据大小592.76 GB数据时间范围 1999-12-31 — 2022-12-31 元数据更新时间2024-08-09 数据集摘要 …...

Django 自定义celery-beat调度器,查询自定义表的Cron表达式进行任务调度

学习目标&#xff1a; 通过自定义的CronScheduler调度器在兼容标准的调度器的情况下&#xff0c;查询自定义任务表去生成调度任务并分配给celery worker进行执行 不了解Celery框架的小伙伴可以先看一下我的上一篇文章&#xff1a;Celery框架组件分析及使用 学习内容&#xff…...

第 12 届蓝桥杯 C++ 青少组中 / 高级组省赛 2021 年 4 月 24 日真题

一、选择题 第 1 题 单选题 题目:在 C++ 中下列哪个不属于字符型常量 ( )。 A. ‘a’ B. ‘\x2A’ C. ‘@’ D. “F” 答案:D 解析:字符型常量使用单引号括起单个字符(如 A、C),或转义字符(如 B 中的十六进制转义字符)。D 选项 “F” 使用双引号,属于字符串常量,而…...

windows远程服务器数据库的搭建和远程访问(Mysql忘记密码通过Navicat连接记录解密密码)

服务器数据库的搭建和远程访问 mysql数据库安装&#xff08;详细&#xff09; window安装mysql详细流程 路程&#xff1a;重设MySQL5密码&#xff0c;发现远程服务器原本有一个MySQL5&#xff0c;尝试在服务器本地建立连接被拒绝&#xff0c;因为不知道密码。 &#xff08;1…...

w~大模型~合集14

我自己的原文哦~ https://blog.51cto.com/whaosoft/13884560 #Attention as an RNN Bengio等人新作&#xff1a;注意力可被视为RNN&#xff0c;新模型媲美Transformer&#xff0c;但超级省内 , 既能像 Transformer 一样并行训练&#xff0c;推理时内存需求又不随 token 数…...

2025平航杯—团队赛

2025平航杯团队赛 计算机取证 分析起早王的计算机检材&#xff0c;起早王的计算机插入过USB序列号是什么(格式&#xff1a;1)分析起早王的计算机检材&#xff0c;起早王的便签里有几条待干(格式&#xff1a;1)分析起早王的计算机检材&#xff0c;起早王的计算机默认浏览器是什…...

5、SpringBoot整合RabbitMQ

5.1 工作队列模式 1、生产者 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</gro…...

深度学习论文: Describe Anything: Detailed Localized Image and Video Captioning

深度学习论文: Describe Anything: Detailed Localized Image and Video Captioning Describe Anything: Detailed Localized Image and Video Captioning PDF: https://arxiv.org/pdf/2504.16072 PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: htt…...

Seata客户端@GlobalTransactional核心源码解析

文章目录 前言一、GlobalTransactional1.1、wrapIfNecessary1.2、handleGlobalTransaction1.3、invoke 二、总结 前言 Seata是阿里开源的分布式事务解决方案。在Spring传统的事务中&#xff0c;开启事务&#xff0c;执行事务&#xff0c;回滚/提交事务&#xff0c;统一由Spring…...

某大麦某眼手机端-抢票

引言 仅供学习研究&#xff0c;欢迎交流 抢票难&#xff0c;难于上青天&#xff01;无论是演唱会、话剧还是体育赛事&#xff0c;大麦网的票总是秒光。作为一名技术爱好者&#xff0c;你是否想过用技术手段提高抢票成功率&#xff1f;本文将为你揭秘大麦手机端抢票的核心技术…...

深入探索ChatClient:简化AI模型交互的强大工具

深入探索ChatClient&#xff1a;简化AI模型交互的强大工具 前言 在人工智能飞速发展的当下&#xff0c;大语言模型&#xff08;LLM&#xff09;的应用越来越广泛。然而&#xff0c;构建基于LLM的应用程序并非易事&#xff0c;通常需要多个组件协同工作&#xff0c;如提示词模…...

AI 知识库:企业知识管理的利器

在数字化转型的今天&#xff0c;企业每天都会产生海量的信息和数据。从客户资料到内部文档&#xff0c;从市场调研到项目经验&#xff0c;这些宝贵的知识资源构成了企业的核心竞争力。然而&#xff0c;你是否注意到这样一个问题&#xff1a;很多企业在快速发展的同时&#xff0…...

【STM32实物】基于STM32的RFID多卡识别语音播报系统设计

演示视频: 基于STM32的RFID多卡识别语音播报系统设计 前言:本项目可实现多个电子标签IC卡RFID识别,刷卡识别后进行中文语音播报反馈,同时进行控制对应的灯光开关。以此也可扩展开发更多功能。 本项目所需主要硬件包括:STM32F103C8T6最小系统板、RFID-RC522模块、五个IC电…...

[实战] Petalinux驱动开发以及代码框架解读

目录 Petalinux驱动开发以及代码框架解读一、引言二、步骤2.1 创建PetaLinux工程2.2 配置硬件描述文件2.3 设备树配置2.4 建立驱动框架2.5 编辑 .bb 文件2.6 编写驱动文件2.7 编写 Makefile2.8 验证配方配置2.9 集成驱动到 RootFS2.10 全系统编译与部署2.11 启动验证 三、框架解…...

ArcGIS Pro几个小知识点分享

相信熟悉ArcGIS 10.X系统的朋友接触ArcGIS Pro或者QGIS的上手难度都很低&#xff0c;因此向大家分享我最近才注意到的一些ArcGIS Pro小的知识点或者注意事项等&#xff0c;用来查缺补漏。如果是GIS新手小白&#xff0c;建议先去了解GIS相关理论基础&#xff0c;再摸索GIS相关软…...

运维仙途 第1章 灵机突现探监控

第1章 灵机突现探监控 情节梗概 凌运维本是青云门杂役弟子&#xff0c;负责看守藏经阁灵脉枢纽。某日子夜&#xff0c;护山大阵突然灵力紊乱&#xff0c;阁中古籍无风自动。危急时刻&#xff0c;他意外触发祖师留下的「混沌钟」&#xff0c;获得观测灵脉状态的能力… 技术映…...

深入解析Java架构师面试:从核心技术到AI应用

深入解析Java架构师面试&#xff1a;从核心技术到AI应用 在互联网大厂的Java求职者面试中&#xff0c;技术深度和项目经验是成功的关键。本文以严肃的面试官与资深Java架构师马架构&#xff08;拥有十年研发及架构设计经验&#xff09;之间的对话为背景&#xff0c;详细展示了…...

Grounding DINO

论文标题&#xff1a; Grounding DINO: Marrying DINO with Grounded Pre-Training for Open-Set Object Detection 代码地址&#xff1a; GitHub - IDEA-Research/GroundingDINO: [ECCV 2024] Official implementation of the paper "Grounding DINO: Marrying DINO …...

MCP协议:自然语言与结构化数据的双向桥梁 ——基于JSON-RPC 2.0的标准化实践

MCP协议&#xff1a;自然语言与结构化数据的双向桥梁 ——基于JSON-RPC 2.0的标准化实践 一、MCP的本质&#xff1a;标准化共识的协议框架 MCP&#xff08;Model Context Protocol&#xff09;是Anthropic于2024年提出的开放通信协议&#xff0c;其核心价值在于建立自然语言…...

区块链+医疗:破解数据共享困局,筑牢隐私安全防线

在医疗健康领域&#xff0c;数据共享与隐私保护一直是一对难以调和的矛盾。一方面&#xff0c;分散在不同机构的医疗数据&#xff08;如电子病历、检查报告、用药记录&#xff09;阻碍了诊疗效率和科研进展&#xff1b;另一方面&#xff0c;患者隐私泄露事件频发&#xff0c;加…...

Arduino IDE中更新esp32 3.2.0版本的办法

在Arduino IDE中更新esp32-3.2.0版本是个不可能的任务&#xff0c;下载文件速度极慢。网上提供了离线的办法&#xff0c;提供了安装文件&#xff0c;但是没有3.2.0的版本。 下面提供了一种离线安装方法 一、腾讯元宝查询解决办法 通过打开开发板管理地址&#xff1a;通过在腾…...

关于 live555延迟优化之缓存区优化“StreamParser::afterGettingBytes() warning: read”” 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/146354088 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

毫米波通信的技术挑战与解决方案

毫米波通信的技术挑战与解决方案 随着5G技术的迅速发展&#xff0c;毫米波通信&#xff08;Millimeter Wave, mmWave&#xff09;作为一种具有巨大潜力的通信技术&#xff0c;正在成为实现超高速数据传输、低延迟和大规模连接的关键。然而&#xff0c;毫米波通信虽然在理论上具…...

软考中级-软件设计师 数据库(手写笔记)

基本概念 数据库分析设计过程 E-R模型 关系模式 关系模式相关名词和完整性约束和关系的三种类型 七种基本算法 并交查和笛卡尔积 投影选择和连接 题 规范化-函数依赖 求候选码 非规范化可能处于的问题 问题 题 关系-模型分解 事务管理 备份和恢复 数据仓库和数据挖掘...

Compose笔记(二十一)--AnimationVisibility

这一节主要了解一下Compose的AnimationVisibility,AnimatedVisibility 是 Jetpack Compose 里用于实现组件可见性动画效果的组件&#xff0c;借助它能让组件在显示和隐藏时带有平滑的过渡动画&#xff0c;从而提升用户体验。现总结如下: API 1. visible 含义&#xff1a;这是一…...

生物化学笔记:神经生物学概论05 感受野 视觉中枢 高级视皮层中的信息走向

信息传递中的“击鼓传花” 新特性的突现 功能柱&#xff1a;简化节点 高级视皮层中的信息走向...

记录idea可以运行但是maven install打包却找不到问题

解决idea使⽤maven多模块install报依赖模块的包找不到的问题 如果被依赖项⽬是springboot项⽬&#xff0c;那么可以把相关的springboot的东西移除掉&#xff0c;改造成普通项⽬。如果不想改造项⽬&#xff0c;那就添加部分的配置&#xff0c;因为springboot项⽬打包的时候会⽣…...

牛客:AB5 点击消除

链接&#xff1a;点击消除_牛客题霸_牛客网 题解&#xff1a; 利用栈&#xff0c;遍历输入的字符串&#xff0c;栈为空则入栈&#xff0c;栈不为空则去除栈顶字符和当前遍历到的字符比较&#xff0c;相等则栈顶字符出栈&#xff0c;当前遍历的字符也不入栈&#xff0c;不相等…...

vue3 动态修改系统title

vue3 动态修改系统title 修改前 修改后 1、封装 useTitle 工具函数 创建组合式 API&#xff0c;通过 watchEffect 监听标题变化&#xff1a; // composables/useTitle.js import { ref, watchEffect } from vue;export function useTitle(initialTitle) {const title r…...

产品经理.产品设计.产品设计工具

一、 产品经理常用工具 1. 业务流程图---系统流程图 业务流程图&#xff0c;面向用户调研&#xff0c;描述业务的流转和数据的处理要求&#xff0c;跟用户和业务方确认&#xff1b;---业务角色的泳道流程图。 系统流程图&#xff0c;面向产品需求设计&#xff0c; prd系描述各…...

kibana重建es索引

kibana如何重命名es索引名 背景 在初期设计es索引文档的时候考虑不是很周全&#xff0c;会多出很多无效字段。如果不删除或禁用对后续数据增量以及文档维护会有不良影响。 技术实现 使用 _reindex 1.执行Reindex # 复制旧索引数据到新索引 POST _reindex {"source&qu…...

windows系统常用快捷键(CMD常用命令,DOS常用命令)

Windows系统常用快捷键 Win E: 打开“文件资源管理器”&#xff08;我的电脑&#xff09;。Win S: 打开“搜索”功能&#xff0c;可以搜索文件、应用、设置等。Win I: 打开“设置”菜单&#xff0c;用于调整系统设置。Win X: 打开“快速链接”菜单&#xff0c;包含电源选项…...