bf算法与kmp算法_bf算法是什么

bf算法与kmp算法_bf算法是什么BF算法和KMP算法可以说是串中重要的算法,也是数据结构必学算法,我以前是不太理解KMP算法的,但是现在说来可以写出程序 理解思想了 也能懂了next数组,若有错误清在评论区指出,一起探讨。1.2.1.1. 2.三.1.算法中最紧要的是理解一个算法的思想,就像是人一样,没有思想与…

最详BF算法和KMP算法"

  作者简介:大家好我是小唐同学(๑>؂<๑),为梦想而奋斗的小唐,让我们一起加油!!!

bf算法与kmp算法_bf算法是什么

个人主页: 小唐同学(๑>؂<๑)的博客主页

博友们如果也是新手入门数据结构我希望大家可以多加练习 数据结构题库在牛客网就有已经给大家附上链接,可以直接点击跳转:刷题点这里

牛客网支持ACM模式哦,刷算法题也很推荐哦!!!

下面上文章——》

bf算法与kmp算法_bf算法是什么

 

BF算法和KMP算法可以说是串中重要的算法,也是数据结构必学算法,我以前是不太理解KMP算法的,但是现在说来可以写出程序 理解思想了 也能懂了next数组,若有错误清在评论区指出,一起探讨。

目录

一、BF算法

1.理解阶段

2.代码阶段

 二、KMP算法

1.理解阶段

1.next数组的获得代码

 2.KMP算法代码如下:

三.BF算法与KMP算法的区别与优缺点


一、BF算法

1.理解阶段

算法中最紧要的是理解一个算法的思想,就像是人一样,没有思想与行尸走肉无异,算法是一样的。BF算法的时间复杂度最理想为O(n)    ——n为子串的长度

 最不理想为O(n*m)            ——————m为主串长度

BF算法又称为简单模式匹配算法     其思想简单  容易理解 但是效率较低(需要回溯)

98eef2361c777583543dfc45d3f78e1a.gif

第一次进行模式匹配   匹配到第3个字符  匹配错误。

97534d439e9e3afbbf5b19289eef9086.gif

进行第2次模式匹配,本次匹配会把子串回溯到起点  主串会回溯到上次进行匹配的起点的下一个位置   可以看到到子串的第2个字符匹配失败 重新回溯

0995a30cea246692aec56ce0f9b88d1f.gif

 第3次进行模式匹配 同上回溯方法   到第5个字符匹配失败 重新回溯

1549297cb2295f3c079d2f5f13c48ffc.gif

第4次进行模式匹配   匹配成功

2.代码阶段

如果说理解重要,但是只处于理解阶段对于一个程序员是远远不够的,还要有代码能力。

先给出BF算法部分代码

我定义返回型为int型   返回第一次出现的位置

int creatBF(char *a,char *b) { 
 //a主串 b子串 
 int i=0,j=0,x=0;
 while(i<strlen(a)&&j<strlen(b)) //子串主串都没有到达最后 到达最后说明匹配不成功 
 {
 	if(a[i]==b[j])
	 {
	 	i++;
	 	j++;
	  } 
 	else
 	{
 		i=x+1; //x存储上一次开始的起点 
		 j=0;    //回溯 
		 x=i;     //记录本次开始的起点 
	 }
 }
 	//跳出循环 则到达a的长度或到达b的长度
	 //到达a 则说明匹配成功
	 //到达b 则说明 匹配不成功 
 	if(j==strlen(b))
 	{
 		return x;
	 }
	 return 0;
 }

测试结果如下:

84544c256b0847ccb3a883f1abbf0811.png

 二、KMP算法

1.理解阶段

KMP算法是BF算法的升级版   相对来说是  理解难度上升 但是效率得到了提高

KMP算法相对与BF算法  是主串不需要回溯   子串是回溯到特定的位置  可以有效减少比较次数

较少运行时间  提高效率

子串回溯   主要看next数组    ,我的理解是next数组是next数组的值-1表示最长前缀的下标

918b89bf85044da19815cc099dcd7cac.png

 b1e8fa2fc69d4a2aaa29ddd903e5b814.png

当子串主串发生失配时   主串不发生回溯,子串会回溯到最长相等前后缀数值的位置

而记录最长相等前后缀的就时next数组 next[j]=k  表示子串中前j-1个字符的最长相等前后缀长度为k-1

下面给出获得next数组的代码

1.next数组的获得代码

void GetNext(char *a,int next [])
{
	//a主串    b子串 
	int j=0; //便利子串 
	int k=-1; //k时子串中每个字符的next值 
	next[0]=-1; 
	while(j<strlen(a)) 
	{
		
	if(k==-1||a[j]==a[k])	
		{
			j++;
			k++;
			next[j]=k;
		}
		else
		k=next[k];
	}
	
}

测试结果如图:

99909c20c0e541948fe2368888e0f22a.png

 2.KMP算法代码如下:

KMP算法的核心在于求next数组     剩下的就是进行比较

int creatKMP(char *a,char *b,int next[])
{ 
//a  主串   b子串 
	int i=0,j=0;
	while(i<strlen(a)&&j<strlen(b))
	{
		if(j==-1||a[i]==b[j])
		{
			i++;
			j++;
		}
		else
		j=next[j];
	}
	if(j>=strlen(b))
{
return (i-strlen(b));//i表示  查找结束在主串中的位置减去子串长度  为首位置 
}
else 
return -1;	
 } 

测试结果如图:

484829cd2c834afdb70553bc03d2e6fc.png

 下面我会给出完整的程序,包括BF和KMP算法 如下:

# include <stdio.h>
#include <string.h>
void GetNext(char *a,int next [])
{
	//a主串    b子串 
	int j=0; //便利子串 
	int k=-1; //k时子串中每个字符的next值 
	next[0]=-1; 
	while(j<strlen(a)) 
	{
		
	if(k==-1||a[j]==a[k])	//表示判断加入后缀 j后是否与会 使最长前后缀增加 a[k] 表示最长前缀的后一个 
		{
			j++; 
			k++; 
			next[j]=k; 
		}
		else
		k=next[k]; 
	}
	
}
int creatKMP(char *a,char *b,int next[])
{ 
//a  主串   b子串 
	int i=0,j=0;
	while(i<strlen(a)&&j<strlen(b))
	{
		if(j==-1||a[i]==b[j])
		{
			i++;
			j++;
		}
		else
		j=next[j];
	}
	if(j>=strlen(b))
{
return (i-strlen(b));//i表示 查找结束在主串中的位置减去子串长度 为首位置 
}
else 
return -1; 
 } 
 int creatBF(char *a,char *b)
 { 
 //a主串    b子串 
 int i=0,j=0,x=0;
 while(i<strlen(a)&&j<strlen(b)) //子串主串都没有到达最后   到达最后说明匹配不成功 
 {
 	if(a[i]==b[j])
	 {
	 	i++;
	 	j++;
	  } 
 	else
 	{
 		i=x+1; //x存储上一次开始的起点 
		 j=0; //回溯 
		 x=i; //记录本次开始的起点 
	 }
 }
 	//跳出循环  则到达a的长度或到达b的长度
	 //到达a    则说明匹配成功
	 //到达b    则说明 匹配不成功 
 	if(j==strlen(b))
 	{
 		return x;
	 }
	 return 0;
 }
int main()
{
	char a[13];
	char b[5];
	scanf("%s%s",a,b);
int t=creatBF(a,b);
	 	printf("%d\n",t);
int next[5];
GetNext(b,next);
//for(int i=0;i<5;i++)
//{
//		printf("%d ",next[i]);
//}
int y=creatKMP(a,b,next);
printf("%d",y); 
}

三.BF算法与KMP算法的区别与优缺点

BF算法是子串主串都需要进行回溯比较浪费时间,效率比较低。

KMP算法是主串不需要回溯,子串只需要根据next数组进行回溯到特定位置

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13902.html

(0)

相关推荐

  • redhat6.7静默安装oracle单机实例[亲测有效]

    redhat6.7静默安装oracle单机实例[亲测有效]1.环境变量配置 修改/etc/hosts文件 vim /etc/hosts 修改/etc/sysctl.conf文件 vim /etc/sysctl.conf fs.aio-max-nr = 10…

    2023-04-21
    130
  • 学习使用PyCharm Debug调试Python程序

    学习使用PyCharm Debug调试Python程序本文将介绍如何在PyCharm中使用调试器Debug调试Python程序。调试器是用于查找和解决软件中的错误的重要工具,它可以帮助程序员更快地找出问题所在且更快地解决问题。在PyCharm中使用调试器Debug可以一步一步地执行程序并查看正在执行的每个代码行,同时还可以检查变量的值和状态。

    2024-07-12
    32
  • mysql数据库02292_MySQL进入

    mysql数据库02292_MySQL进入MySQL数据库 前言: 前面我们了解了什么是数据库,什么是MySQL数据库以及如何运用,接下来我们接着深入学习MySQL。 (提前声明,以下所提供的事例不标准,仅供参考) 数据库的备份与还原: 备份

    2023-02-11
    164
  • Linux下Mysql修改密码 重启mysql服务

    Linux下Mysql修改密码 重启mysql服务
    如果忘记mysql的密码 修改配置文件跳过密码直接登录 在[mysqld]下面添加 vim /etc/my.cnf skip-grant-tablses 重…

    2023-04-08
    148
  • css常见布局方式_界面布局方式

    css常见布局方式_界面布局方式本文思维导图,欢迎补充 本文首发于我的个人网站:http://cherryblog.site 前言 温馨提示:本文较长,图片较多,本来是想写一篇 CSS 布局方式的,但是奈何 CSS 布局方式种类太多并且实现方法太多,所以本文主要是介绍 flex 布局和 grid 布局,以及 C…

    2023-07-21
    104
  • 面向鲲鹏和昇腾的创新架构

    面向鲲鹏和昇腾的创新架构面向鲲鹏的创新架构 华为的鲲鹏920处理器以及后续的处理器系列,与传统的英特尔 x86处理器相比,存在以下3方面的不同: 具有更多计算核心,使得可以并行运行的算力大幅增加。 具有更加显著的 NUMA…

    2023-04-14
    148
  • redis底层算法_Redis 命令

    redis底层算法_Redis 命令Redis底层函数详解 1. serverCron 函数 它负责管理服务器的资源,并维持服务器的正常运行。在执行 serverCron 函数的过程中会调用相关的子函数,如 trackOperation

    2023-02-11
    133
  • Python获取变量类型

    Python获取变量类型Python是一种解释性语言,因此不需要在编写代码之前声明变量类型。这个特性使得代码更加灵活和易于编写,同时也更容易出错。在Python中,我们可以使用type()函数来获取变量的类型,这对于初学者来说非常重要。

    2024-07-13
    43

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注