【数据结构入门精讲 | 第十六篇】并查集知识点及考研408、企业面试练习

上一篇中我们进行了散列表的相关练习,在这一篇中我们要学习的是并查集。

在这里插入图片描述

目录

    • 概念
    • 伪代码
    • 选择题
    • 填空题
    • 编程题
      • 7-1 朋友圈
      • R7-1 笛卡尔树
      • R7-2 部落
      • R7-3 秀恩爱分得快

在许多实际应用场景中,我们需要对元素进行分组,并且在这些分组中进行查询和修改操作。比如,在图论中,我们需要将节点按照连通性进行分组,以便进行最小生成树、最短路径等算法;在计算机视觉中,我们需要将像素进行分组,以便进行图像分割和对象识别等任务。而并查集正是为了解决这些问题而被提出来的一种数据结构。

概念

并查集(Disjoint Set)是一种用于处理元素分组的数据结构,通常用于解决一些与等价关系有关的问题,比如连通性的判断、最小生成树算法中的边的合并等。

在这里插入图片描述

并查集中的每个元素都属于一个集合,每个集合都有一个代表元素(也称为根节点),代表元素可以用来表示整个集合。并查集支持三个基本操作:

1.MakeSet(x):创建一个只包含元素 x 的新集合;
2.Find(x):返回元素 x 所属的集合的代表元素;
3.Union(x, y):将元素 x 和 y 所属的集合合并成一个新集合。

其中,Find 操作可以使用路径压缩(Path Compression)和按秩合并(Union by Rank)优化,以提高查询效率。

并查集的应用非常广泛,比如在图论算法中求解连通性、求解最小生成树等问题时都会用到。

伪代码

// 初始化并查集,每个元素单独成集合
function MakeSet(x)
    x.parent = x
    x.rank = 0

// 查找元素所属的集合(根节点),并进行路径压缩
function Find(x)
    if x.parent != x
        x.parent = Find(x.parent) // 路径压缩:将x的父节点设为根节点
    return x.parent

// 合并两个集合,按秩合并
function Union(x, y)
    xRoot = Find(x)
    yRoot = Find(y)
    if xRoot == yRoot
        return // 已经在同一个集合中,无需合并
    if xRoot.rank < yRoot.rank
        xRoot.parent = yRoot
    else if xRoot.rank > yRoot.rank
        yRoot.parent = xRoot
    else
        yRoot.parent = xRoot
        xRoot.rank = xRoot.rank + 1

接下来,让我们进行并查集的相关练习。

选择题

1.在这里插入图片描述

选B

2.在这里插入图片描述

解析:
1  -4   1  1  -3  4  4  8  -2
0   1   2  3   4  5  6  7   8


1对应-4,则1是根节点且有4个子孙
又因为023都对应1
所以
      1
   0 2 3 null
   
   
4对应-3,则4是根节点且有3个子孙
又因为56都对应4
所以
    4
  5  6 null
  
  
8对应-2,则8是根节点且有2个子孙
又因为7对应8
所以
    8
  7 null
  
将68所在的集合合并,且小集合合并到大集合
则
    4
  5  6 8
      7 null
所以树根是4,对应的编号是-5-表示树根,5表示4的子孙个数)

3.在这里插入图片描述

可以画出来对应的树
然后把小树连到大树上
接着从17遍历
如果有父节点,给出父节点的值
如果它本身是根节点,则给出负号和子孙个数

在这里插入图片描述

填空题

在这里插入图片描述

在这里插入图片描述

编程题

7-1 朋友圈

某学校有N个学生,形成M个俱乐部。每个俱乐部里的学生有着一定相似的兴趣爱好,形成一个朋友圈。一个学生可以同时属于若干个不同的俱乐部。根据“我的朋友的朋友也是我的朋友”这个推论可以得出,如果A和B是朋友,且B和C是朋友,则A和C也是朋友。请编写程序计算最大朋友圈中有多少人。

输入格式:

输入的第一行包含两个正整数N(≤30000)和M(≤1000),分别代表学校的学生总数和俱乐部的个数。后面的M行每行按以下格式给出1个俱乐部的信息,其中学生从1~N编号:

第i个俱乐部的人数Mi(空格)学生1(空格)学生2 … 学生Mi

输出格式:

输出给出一个整数,表示在最大朋友圈中有多少人。

输入样例:

7 4
3 1 2 3
2 1 4
3 5 6 7
1 6

输出样例:

4
#include<stdio.h> 

int a[30001];  // 定义数组a,用于存储并查集的父节点信息
int search(int b){  // 查找元素所属的集合(根节点)
	if(a[b]<0){  // 如果a[b]小于0,说明b是根节点
		return b;  // 返回b作为集合的代表元素
	}else{
		return search(a[b]);  // 否则递归查找父节点,直到找到根节点
	}
}

void function(int m,int n){  // 合并两个集合
	int x,y;
	x=search(m);  // 查找m所属的集合(根节点)
	y=search(n);  // 查找n所属的集合(根节点)
	if(x!=y){  // 如果m和n不在同一个集合中
		a[x]+=a[y];  // 将集合y的大小加到集合x上
		a[y]=x;  // 将集合y的父节点指向集合x
	}
}

int main(){
	int m,n;
	scanf("%d %d",&n,&m);  // 输入学生数量n和关系数量m
	int i;
	for(i=0;i<=n;i++){  // 初始化并查集,每个元素单独成集合
		a[i]=-1;  // 初始时每个元素的父节点为自身,且集合大小为1
	}
	int stu,j,num,num1;
	for(i=0;i<m;i++){  // 处理每组关系
		scanf("%d",&stu);  // 输入每组关系中学生的数量
		for(j=0;j<stu;j++){  // 输入每组关系中的学生编号
			scanf("%d",&num);
			if(j==0){
				num1=num;  // 记录第一个学生的编号
			}else{
				function(num1,num);  // 合并这组关系中的学生
			}
		}
	}
	int min;
	min=a[1];
	for(i=2;i<n;i++){  // 找到集合中最小的负数,作为集合大小的相反数
		if(min>a[i]){
			min=a[i];
		}
	}
	printf("%d",-min);  // 输出最少需要分成的组数
}

R7-1 笛卡尔树

笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大。其次所有结点的K2关键字满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中所有结点的K2值小。给定一棵二叉树,请判断该树是否笛卡尔树。

输入格式:

输入首先给出正整数N(≤1000),为树中结点的个数。随后N行,每行给出一个结点的信息,包括:结点的K1值、K2值、左孩子结点编号、右孩子结点编号。设结点从0~(N-1)顺序编号。若某结点不存在孩子结点,则该位置给出−1。

输出格式:

输出YES如果该树是一棵笛卡尔树;否则输出NO

输入样例1:

6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 21 -1 4
15 22 -1 -1
5 35 -1 -1

输出样例1:

YES

输入样例2:

6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 11 -1 4
15 22 -1 -1
50 35 -1 -1

输出样例2:

NO
#include<bits/stdc++.h>
using namespace std;
struct Node{
    int k1;
    int k2;
    int left_c;
    int right_c;
}a[1200];  // 定义结构体Node,表示二叉树的每个节点
int root,flag=1;  // 定义变量root表示根节点,flag表示是否符合条件
int b[1200];  // 定义数组b,用于标记每个节点是否有左右孩子
int zhongxu[1200],cnt=0;  // 定义数组zhongxu,存储中序遍历序列,cnt为元素数量

void midorder(int root){  // 中序遍历二叉树
    if(root!=-1){  // 如果根节点不为空
        midorder(a[root].left_c);  // 遍历左子树
        zhongxu[cnt]=a[root].k1;  // 将当前节点的值存入中序遍历序列中
        cnt++;  // 记录元素数量
        midorder(a[root].right_c);  // 遍历右子树
    }
}

void judgeheap(int root){  // 判断是否为堆
    int left,right;
    if(a[root].left_c!=-1){  // 如果左孩子存在
        left=a[root].left_c;
        if(a[left].k2<a[root].k2){  // 如果左孩子的值小于根节点的值
            flag=0;  // 不符合堆的条件
            return ;
        }
        judgeheap(left);  // 递归遍历左子树
    }
    if(a[root].right_c!=-1){  // 如果右孩子存在
        right=a[root].right_c;
        if(a[right].k2<a[root].k2){  // 如果右孩子的值小于根节点的值
            flag=0;  // 不符合堆的条件
            return ;
        }
        judgeheap(right);  // 递归遍历右子树
    }
}

int main()
{
    int n;
    cin>>n;  // 输入节点数量n
    int i,K1,K2,Left,Right;
    memset(b,0,sizeof(b));  // 初始化数组b,全部置为0
    for(i=0;i<n;i++)  // 处理每个节点的信息
    {
        scanf("%d %d %d %d",&K1,&K2,&Left,&Right);  // 输入节点的值、权值、左右孩子的编号
        a[i].k1=K1;  // 将节点的值存入结构体
        a[i].k2=K2;  // 将节点的权值存入结构体
        a[i].left_c=Left;  // 将左孩子编号存入结构体
        a[i].right_c=Right;  // 将右孩子编号存入结构体
        if(Left!=-1)  // 如果左孩子存在
            b[Left]=1;  // 标记左孩子编号为1
        if(Right!=-1)  // 如果右孩子存在
            b[Right]=1;  // 标记右孩子编号为1  
    }  
    for(i=0;i<n;i++){  // 找到根节点
        if(b[i]==0){  // 如果节点没有左右孩子,说明其为根节点
            root=i;
            break;
        }
    }
    midorder(root);  // 中序遍历二叉树,得到中序遍历序列
    for(i=1;i<cnt;i++){  // 判断是否为完全二叉树
        if(zhongxu[i]<=zhongxu[i-1]){  // 如果中序遍历序列不是单调递增的
            flag=0;  // 不符合完全二叉树的条件
            break;
        }
    }
    judgeheap(root);  // 判断是否为堆
    if(flag)  // 如果符合条件
        printf("YES\n");  // 输出YES
    else
       printf("NO\n");  // 输出NO
    return 0;
}

R7-2 部落

在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。

输入格式:

输入在第一行给出一个正整数N(≤104),是已知小圈子的个数。随后N行,每行按下列格式给出一个小圈子里的人:

K P[1] P[2] ⋯ P[K]

其中K是小圈子里的人数,P[i](i=1,⋯,K)是小圈子里每个人的编号。这里所有人的编号从1开始连续编号,最大编号不会超过104。

之后一行给出一个非负整数Q(≤104),是查询次数。随后Q行,每行给出一对被查询的人的编号。

输出格式:

首先在一行中输出这个社区的总人数、以及互不相交的部落的个数。随后对每一次查询,如果他们属于同一个部落,则在一行中输出Y,否则输出N

输入样例:

4
3 10 1 2
2 3 4
4 1 5 7 8
3 9 6 4
2
10 5
3 7

输出样例:

10 2
Y
N
#include<iostream>
#include<set>
#include<cstdio>
using namespace std;
int pre[10010];  // 定义数组pre,用于存储每个元素的祖先

int find(int x){  // 查找操作,返回x的祖先
    if(pre[x]==x) return x;
    return pre[x]=find(pre[x]);
} 

void unite(int x,int y){  // 合并操作,将x所在集合和y所在集合合并
    x=find(x);
    y=find(y);
    if(x!=y)
        pre[x]=y;
}

int main(){
    int n,x,y,m,a;
    for(int i=1;i<=10000;i++) pre[i]=i;  // 初始化每个元素的祖先为自身
    set<int>s,ss;  // 定义两个set容器s和ss,分别用于存储所有元素和合并后的元素
    cin>>n;  // 输入集合数量n
    while(n--){  // 处理每个集合
        cin>>m;  // 输入集合中元素数量m
        cin>>x;  // 输入第一个元素的值
        s.insert(x);  // 将第一个元素插入到集合s中
        for(int i=1;i<m;i++){  // 处理集合中的其他元素
            cin>>y;  // 输入元素的值
            s.insert(y);  // 将元素插入到集合s中
            unite(x,y);  // 将元素x和元素y所在的集合合并
        }
    }
    set<int>::iterator it;  // 定义迭代器it,用于遍历集合s中的元素
    for(it=s.begin();it!=s.end();it++)  // 遍历集合s中的元素
        ss.insert(find(*it));  // 将每个元素的祖先插入到集合ss中
    printf("%d %d\n",s.size(),ss.size());  // 输出集合s的大小和集合ss的大小
    cin>>a;  // 输入查询次数a
    while(a--){  // 处理每次查询
        cin>>x>>y;  // 输入要查询的两个元素
        if(find(x)==find(y))  // 如果两个元素的祖先相同
            puts("Y");  // 输出Y
        else
            puts("N");  // 输出N
    }
    return 0;
}

R7-3 秀恩爱分得快

古人云:秀恩爱,分得快。

互联网上每天都有大量人发布大量照片,我们通过分析这些照片,可以分析人与人之间的亲密度。如果一张照片上出现了 K 个人,这些人两两间的亲密度就被定义为 1/K。任意两个人如果同时出现在若干张照片里,他们之间的亲密度就是所有这些同框照片对应的亲密度之和。下面给定一批照片,请你分析一对给定的情侣,看看他们分别有没有亲密度更高的异性朋友?

输入格式:

输入在第一行给出 2 个正整数:N(不超过1000,为总人数——简单起见,我们把所有人从 0 到 N-1 编号。为了区分性别,我们用编号前的负号表示女性)和 M(不超过1000,为照片总数)。随后 M 行,每行给出一张照片的信息,格式如下:

K P[1] ... P[K]

其中 K(≤ 500)是该照片中出现的人数,P[1] ~ P[K] 就是这些人的编号。最后一行给出一对异性情侣的编号 A 和 B。同行数字以空格分隔。题目保证每个人只有一个性别,并且不会在同一张照片里出现多次。

输出格式:

首先输出 A PA,其中 PA 是与 A 最亲密的异性。如果 PA 不唯一,则按他们编号的绝对值递增输出;然后类似地输出 B PB。但如果 AB 正是彼此亲密度最高的一对,则只输出他们的编号,无论是否还有其他人并列。

输入样例 1:

10 4
4 -1 2 -3 4
4 2 -3 -5 -6
3 2 4 -5
3 -6 0 2
-3 2

输出样例 1:

-3 2
2 -5
2 -6

输入样例 2:

4 4
4 -1 2 -3 0
2 0 -3
2 2 -3
2 -1 2 
-3 2

输出样例 2:

-3 2
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define maxn 4019
int n,m,k[maxn],A,B,sexa,sexb; //人数,图片数,每张图片的人数数组,两个人的编号,两个人的性别
int fu[maxn],pic[maxn][maxn],pwa[maxn],pwb[maxn]; //人的性别数组,图片中的人物编号数组,用于计算亲密度的临时数组
double pa[maxn],pb[maxn]; //与A、B的亲密度数组
vector<int>ans1,ans2; //存储亲密度最高的人的编号
 
struct gg
{
    int id; //人的编号
    double v; //与A或B的亲密程度
} p1[maxn],p2[maxn]; //用于排序的临时结构体数组
 
//读取带负号的字符串并转换为整数
int read(char*str,int ans,int *fu_)
{
    if(str[0]=='-')
    {
        int len=strlen(str);
        rep(t,1,len)
        ans=ans*10+str[t]-'0';
        *fu_=-1; //标记为负数
    }
    else
    {
        int len=strlen(str);
        rep(t,0,len)
        ans=ans*10+str[t]-'0';
        *fu_=0; //标记为非负数
    }
    return ans;
}
 
//根据性别计算与A或B的亲密度
void getpwith_(int index,int row)
{
    memset(pwa,0,sizeof(pwa)); //清空临时数组
    int sex=index==1?sexa:sexb; //根据index确定性别
 
    rep(j,0,k[row])
    {
        int peo=pic[row][j];
        if(fu[peo]!=sex) //与A或B的性别不同的人,亲密度加1
        {
            if(index)
                pwa[peo]=1;
            else
                pwb[peo]=1;
        }
    }
}
 
//比较函数,用于排序
int cmp(gg x,gg y)
{
    if(x.v!=y.v)
        return x.v>y.v;
    return x.id<y.id;
}
 
int main()
{
    scanf("%d%d",&n,&m); //读取人数和图片数
    rep(i,0,m)
    {
        scanf("%d",&k[i]); //读取每张图片中的人数
        char str[maxn];
 
        //(1)读取pic[][]:存储出现过的每张图片里的具体人物编号和性别
        rep(j,0,k[i])
        {
            scanf("%s",str);
            //读取多位数
            int fu_;
            pic[i][j]=read(str,pic[i][j],&fu_); //读取人物编号并标记性别
            fu[pic[i][j]]=fu_; //记录人的性别
        }
    }
    char AA[maxn],BB[maxn];
    scanf("%s%s",AA,BB); //读取两个人的编号字符串
    A=read(AA,0,&sexa); //将字符串转换为整数,并记录性别
    B=read(BB,0,&sexb);
 
    /*当某个人和谁的好感度都是0,这时候只输出所有异性*/
    rep(i,0,n){
        if(fu[i]==sexa)
            pa[i]+=-1; //当与A的亲密度为0时,将其置为-1
        if(fu[i]==sexb)
            pb[i]+=-1; //当与B的亲密度为0时,将其置为-1
    }
 
    //(2)计算flaga,flagb(局部变量):标记计算m张图片里是否出现过A,B
    rep(i,0,m)
    {
        int flaga=0;
        int flagb=0;
        rep(j,0,k[i])
        {
            if(pic[i][j]==A)
                flaga=1; //标记A在当前图片中出现过
            if(pic[i][j]==B)
                flagb=1; //标记B在当前图片中出现过
        }
 
        if(flaga) //计算A在局部和每个人同框的次数
        {
            getpwith_(1,i); //计算与A的亲密度
            rep(j,0,k[i])
            pa[pic[i][j]]+=pwa[pic[i][j]]/double(k[i]); //累加亲密度
        }
        if(flagb)//计算B在局部和每个人同框的次数
        {
            getpwith_(0,i); //计算与B的亲密度
            rep(j,0,k[i])
            pb[pic[i][j]]+=pwb[pic[i][j]]/double(k[i]); //累加亲密度
        }
    }
 
    rep(i,0,n)
        p1[i].id=i,p1[i].v=pa[i],p2[i].id=i,p2[i].v=pb[i]; //初始化结构体数组
 
    sort(p1,p1+n,cmp); //按亲密度排序
    sort(p2,p2+n,cmp);
 
    double maxa=p1[0].v; //A的最大亲密度
    rep(i,0,n)
    {
        if(p1[i].v!=maxa)
            break;
        else
            ans1.push_back(p1[i].id); //将亲密度最高的人的编号存入ans1
    }
 
    double maxb=p2[0].v; //B的最大亲密度
    rep(i,0,n)
    {
        if(p2[i].v!=maxb)
            break;
        else
            ans2.push_back(p2[i].id); //将亲密度最高的人的编号存入ans2
    }
 
    int len1=ans1.size();
    int f1=0;
    rep(i,0,len1)
    {
        if(pa[ans1[i]]==pa[B]) //如果与B的亲密度与A的亲密度相同,则标记f1
            f1=1;
    }
 
    int len2=ans2.size();
    int f2=0;
    rep(i,0,len2)
    {
        if(pb[ans2[i]]==pb[A]) //如果与A的亲密度与B的亲密度相同,则标记f2
            f2=1;
    }
 
    if(f1&&f2) //如果同时满足与A和B的亲密度相同的人存在,输出两个人的编号
    {
        if(sexa==-1)
            cout<<'-'<<A<<" ";
        else
            cout<<A<<" ";
        if(sexb==-1)
            cout<<'-'<<B<<endl;
        else
            cout<<B<<endl;
    }
    else //否则,分别输出与A和B亲密度最高的人的编号
    {
        rep(i,0,len1)
        {
            if(sexa==-1)
                cout<<'-'<<A<<" ";
            else
                cout<<A<<" ";
            if(fu[ans1[i]]==-1)
                cout<<'-'<<ans1[i]<<endl;
            else
                cout<<ans1[i]<<endl;
        }
        rep(i,0,len2)
        {
            if(sexb==-1)
                cout<<'-'<<B<<" ";
            else
                cout<<B<<" ";
            if(fu[ans2[i]]==-1)
                cout<<'-'<<ans2[i]<<endl;
            else
                cout<<ans2[i]<<endl;
        }
 
    }
 
    return 0;
}

以上就是并查集的知识点及相关练习了,在下一篇文章中我们将学习图的相关知识点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/265841.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

常用Python自动化测试框架有哪些?优缺点对比

随着技术的进步和自动化技术的出现&#xff0c;市面上出现了一些自动化测试框架。只需要进行一些适用性和效率参数的调整&#xff0c;这些自动化测试框架就能够开箱即用&#xff0c;大大节省了测试时间。而且由于这些框架被广泛使用&#xff0c;他们具有很好的健壮性&#xff0…

代码随想录第三十九天(一刷C语言)|零钱兑换完全平方数

创作目的&#xff1a;为了方便自己后续复习重点&#xff0c;以及养成写博客的习惯。 一、零钱兑换 思路&#xff1a;参考carl文档 1、确定dp数组以及下标的含义&#xff1a;凑足总额为j所需钱币的最少个数为dp[j]。 2、确定递推公式&#xff1a;凑足总额为j - coins[i]的最…

先进制造身份治理现状洞察:从手动运维迈向自动化身份治理时代

在新一轮科技革命和产业变革的推动下&#xff0c;制造业正面临绿色化、智能化、服务化和定制化发展趋势。为顺应新技术革命及工业发展模式变化趋势&#xff0c;传统工业化理论需要进行修正和创新。其中&#xff0c;对工业化水平的判断标准从以三次产业比重标准为主回归到工业技…

WEB 3D技术 three.js 通过lil-gui 控制x y z轴数值 操作分组 设置布尔值控制 颜色材质控制

上文 WEB 3D技术 three.js 通过lil-gui管理公共事件中 我们用 lil-gui 处理了一下基础事件和按钮的管理 那么 本文 我们来具体说说它能做的其他事 我们先将基础代码改成这样 import ./style.css import * as THREE from "three"; //引入lil-gui import { GUI } fro…

web逆向经验

一、JS逆向调试流程 如果网页有跳转&#xff0c;必须勾选 preservelog 防止丢包看一下有没有框架 右键查看框架源代码(弹出式登陆界面)登陆尽量使用错误密码 防止跳转查看关键登陆包 分析哪些参数是加密的使用别的浏览器分析哪些参数是固定的值初步猜测加密方法搜索&#xff0…

【Java】从JDK 8迁移到JDK后续版本

自我介绍 做一个简单介绍&#xff0c;酒架年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【…

MySQL 事务的ACID特性

MySQL事务是什么&#xff0c;它就是一组数据库的操作&#xff0c;是访问数据库的程序单元&#xff0c;事务中可能包含一个或者多个 SQL 语句。这些SQL 语句要么都执行、要么都不执行。我们知道&#xff0c;在MySQL 中&#xff0c;有不同的存储引擎&#xff0c;有的存储引擎比如…

凸优化 2:如何判定凸函数?

凸优化 2&#xff1a;如何判定凸函数&#xff1f; 如何判断一个目标函数是凸函数&#xff1f;如果是凸函数&#xff0c;那ta的定义域是凸集合 一个函数求俩次梯度&#xff0c;大于等于0&#xff0c;那这个函数就是一个凸函数在同样条件下&#xff0c;怎么设计为凸函数模型&…

使用 Elasticsearch 检测抄袭 (二)

我在在之前的文章 “使用 Elasticsearch 检测抄袭 &#xff08;一&#xff09;” 介绍了如何检文章抄袭。这个在许多的实际使用中非常有意义。我在 CSDN 上的文章也经常被人引用或者抄袭。有的人甚至也不用指明出处。这对文章的作者来说是很不公平的。文章介绍的内容针对很多的…

【星海出品】Keepalived 使用基础案例 (二)

keepalived 使用 [rootmaster ~]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalivedglobal_defs { //全局配置notification_email { //定义报警收件人邮件地址acassenfirewall.locfailoverfirewall.locsysadminfirewall.loc}notification_…

ECMAScript基础入门:从语法到应用

在此之前我以及发布过关于JavaScript基础知识点大家也可以参考 大家有关于JavaScript知识点不知道可以去 &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&#xff1a;ajax知识点 &#x1f389;欢迎关注…

redis常见数据类型

目录 1.基本全局命令 2.数据结构和内部编码 3.单线程架构 1.基本全局命令 Redis有5种数据结构,但它们都是键值对种的值&#xff0c;对于键来说有一些通用的命令。 KEYS 返回所有满足样式(pattern) 的key。支持如下统配样式。 h?llo 匹配 hello, hallo和hxllo h*llo匹配h…

机场信息集成系统系列介绍(6):机场协同决策支持系统ACDM

目录 一、背景介绍 1、机场协同决策支持系统是什么&#xff1f; 2、发展历程 3、机场协同决策参与方 4、相关定义 二、机场协同决策ACDM的建设目标 &#xff08;一&#xff09;机场协同决策支持系统的宏观目标 1、实现运行数据共享和前序航班信息透明化 2、实现地面资源…

Linux常用基本命令(三)

一、显示命令 1. cat 通式&#xff1a;cat 选项 文件名 只能看普通的文本文件 缺点&#xff1a;如果内容过多会显示不全 选项效果-n显示行号包括空行-b跳过空白行编号-s讲所有的连续的多个空行替换为一个空行&#xff08;压缩成一个空行&#xff09;-A显示隐藏字符 三个标准文件…

十四、W5100S/W5500+RP2040之MicroPython开发<MQTTThingSpeak示例>

文章目录 1. 前言2. 平台操作流程3. WIZnet以太网芯片4. 示例讲解以及使用4.1 程序流程图4.2 测试准备4.3 连接方式4.4 相关代码4.5 烧录验证 5. 注意事项6. 相关链接 1. 前言 在这个智能硬件和物联网时代&#xff0c;MicroPython和树莓派PICO正以其独特的优势引领着嵌入式开发…

使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错问题

目录 1、问题说明 2、问题分析思路 3、问题分析过程 3.1、使用Dependency Walker打开软件主程序&#xff0c;查看库与库的依赖关系&#xff0c;查看出问题的库 3.2、使用PE工具查看dll库的时间戳 3.3、解决办法 4、最后 VC常用功能开发汇总&#xff08;专栏文章列表&…

【数据结构】线性表

一.线性表 1.定义&#xff1a; n个同类型数据元素的有限序列&#xff0c;记为 L为表名&#xff0c;i为数据元素在线性表中的位序&#xff0c;n为线性表的表长&#xff0c;n0时称为空表。 2.数据元素之间的关系&#xff1a; 直接前驱和直接后继 3.抽象数据类型线性表的定义…

PADS Layout安全间距检查报错

问题&#xff1a; 在Pads Layout完成layout后&#xff0c;进行工具-验证设计安全间距检查时&#xff0c;差分对BAK_FIXCLK_100M_P / BAK_FIXCLK_100M_N的安全间距检查报错&#xff0c;最小为3.94mil&#xff0c;但是应该大于等于5mil&#xff1b;如下两张图&#xff1a; 检查&…

SpringBoot的配置高级

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

【JMeter】使用内网负载机(Linux)执行JMeter性能测试

一、背景 ​ 在我们工作中有时候会需要使用客户提供的内网负载机进行性能测试&#xff0c;一般在什么情况下我们需要要求客户提供内网负载机进行性能测试呢&#xff1f; 遇到公网环境下性能测试达到了带宽瓶颈。那么这时&#xff0c;我们就需要考虑在内网环境负载机下来执行我们…