预备役2022.1.19学习总结11

 今天我看了一下KMP算法,神奇的是我知道它每个字在讲什么,但是写了一个题怎么都过不了。

讲讲我看到的 数据结构KMP算法配图详解(超详细)_哈顿之光的博客-CSDN博客_数据结构kmp算法详解

KMP算法的作用是在一个已知字符串中查找子串的位置,也叫做串的模式匹配

朴素的模式匹配:从主串s 和子串t 的第一个字符开始,将两字符串的字符一一比对,如果出现某个字符不匹配,主串回溯到第二个字符,子串回溯到第一个字符再进行一一比对。如果出现某个字符不匹配,主串回溯到第三个字符,子串回溯到第一个字符再进行一一比对…一直到子串字符全部匹配成功。(这种方法是在查找字串的时候一下就想到的,但是效率太低,最坏的情况下时间复杂度为O(m*n)

我之前不理解的地方:不知道怎么看,现在知道原来如此

一个字符串最长相等前缀和后缀。

构造next数组关键的地方:每一个字符前的字符串都有最长相等前后缀,而且最长相等前后缀的长度是我们移位的关键,用一个next数组存储子串的最长相等前后缀的长度

 下次比较的地方就是不匹配的字符前的字符串 最长相等前后缀的长度。

也是不匹配的字符处的next数组next[5]应该保存的值,也是子串回溯后应该对应的字符的下标

next数组作用有两个:

①next[i]的值表示下标为i的字符前的字符串最长相等前后缀的长度。

②next[i]的值表示下标为i的字符前的字符串最长相等前后缀的长度。

并查集

并查集详解 ——图文解说,简单易懂(转)_多反思,多回顾,要坚持。-CSDN博客_并查集详解

刷了3个题:

题一:P3367 【模板】并查集 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

模板题:主要是合并,合并在一个根节点之下,判断是不是一个集合,只要知道它们的根节点是不是一样就好了。

#include<stdio.h>
int pre[10010];
int find(int x)
{
	if(pre[x]==x)//如果x的父节点是它自己,那么就是根节点
	    return x;
	 return pre[x]=find(pre[x]);//递归的方法查找根节点,回溯时改变当前节点的父节点,直接指向根节点 
}
/*
int Find_Set2(int x)
{
    int y = x;
    while(y!= -1)
        y = father[y];
    return y;
}
*/ 
int main()
{
	int n,m,z,x,y;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	  pre[i]=i;//它的上级是它自己
	  for(int i=0;i<m;i++)
	  {
	  	 scanf("%d%d%d",&z,&x,&y);
	  	 if(z==1) //合并操作 
	  	   {
	  	   	pre[find(y)]=find(x);
			}
		 else
		 {
		 	//查询操作,判断它两的根节点是否相等 
		   if(find(x)==find(y))
		      printf("Y\n");
			 else	
			   printf("N\n");
		  }
	   } 
}

题二:P1551 亲戚 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

和上面这个题基本上一样,就不解释了

#include<stdio.h>
int pre[10010];
int find(int x)
{
	if(pre[x]==x)//如果x的父节点是它自己,那么就是根节点 
	    return x;
	 return pre[x]=find(pre[x]);//递归的方法查找根节点,回溯时改变当前节点的父节点,直接指向根节点 
}
/*
int Find_Set2(int x)
{
    int y = x;
    while(y!= -1)
        y = father[y];
    return y;
}
*/ 
int main()
{
	int n,m,p,m1,m2;
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=n;i++)
	  pre[i]=i;//它的上级是它自己
	  for(int i=0;i<m;i++)
	  {
	  	 scanf("%d%d",&m1,&m2); 
	  	  pre[find(m2)]=find(m1);//连接子集(将m2的根节点的父节点变成m1的根节点 
        }
        for(int i=0;i<p;i++)
        {
        	scanf("%d%d",&m1,&m2); 
		 	//查询操作 ,如果两个根节点说一样的证明在一棵树上,是亲戚关系 
		   if(find(m1)==find(m2))
		      printf("Yes\n");
			 else	
			   printf("No\n");
	   } 
}

题三:P1827 [USACO3.4]美国血统 American Heritage - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

没过。。。。。

明天还是刷题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值