串匹配算法 BF算法 KMP算法 C语言实现

BF算法

  BF算法也称朴素算法,思想简单,但效率较低。代码如下:

#include<stdio.h>
#include<string.h>
//s是主串,p是子串,从s串的pos位置开始搜索
int BF(char* s,char* p,int pos)//时间复杂度O(n*m)(存在回退,n为s串长度,m为p串长度)
{
	if(s==NULL||p==NULL)
 	{
  		return -1;
 	}
 	int lens=strlen(s);
 	int lenp=strlen(p);
 	if(lens<lenp)
 	{
 		return -1;
 	}
  	int i=pos;
 	int j=0;

	while(i<lens&&j<lenp)
 	{
  		if(s[i]==p[j])
 		{
   			i++;
   			j++;
  		}
 		else  //失配
  		{
   			i=i-j+1;
   			j=0;
  		}
 	}
 	if(j>=lenp)//在s串中找到了与p串相等的子串,返回其起始位置
 	{
  		return i-j;
 	}
 	return -1;//没找到
}

int main()
{
 	char* s="abbbacabcdabcde";
 	char* p="abcd";
 	printf("匹配的位置:%d\n",BF(s,p,3));
 	return 0;
}

运行结果如下:
在这里插入图片描述

KMP算法

  在p串中,存在两个最长的相等真子串,一个以0位置开始,一个以j-1位置结束,k就是真子串的长度.

代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//规定next[0]=-1;next[1]=0;
void GetNext(int* next,char* p)
{
 	int lenp=strlen(p);
 	next[0]=-1;
 	next[1]=0;
 	int m=1;
 	int x=0;
 	while(m<lenp)
 	{
  		if(x==-1||p[m]==p[x])
  		{
   			next[m+1]=x+1;
   			m++;
   			x++;
  		}
  		else
  		{
   			x=next[x];
  		}
 	}
}

int KMP(char* s,char* p,int pos)
{
 	if(s==NULL||p==NULL)
 	{
  		return -1;
 	}
 	int lens=strlen(s);
 	int lenp=strlen(p);
 	if(lens<lenp)
 	{
  		return -1;
 	}
 	int i=pos;
 	int j=0;
 	int* next=(int*)malloc(sizeof(int)*lenp);
 	if(next==NULL)return -1;//申请失败

	GetNext(next,p);
 	for(int l=0;l<lenp;++l)
 	{
  		printf("%d ",next[l]);
 	}
 	printf("\n");
 	while(i<lens&&j<lenp)
 	{
  		//j==-1说明p串中第一个位置失配
  		if(j==-1||s[i]==p[j])
  		{
   			i++;
   			j++;
  		}
  		else
  		{
   			j=next[j];
  		}
 	}
 	if(j>=lenp)
 	{
  		return i-j;
 	}
 	free(next);
 	return -1;
}

int main()
{
 	char* s="abcabcaabcdabcde";
 	char* p="abcde";

	printf("相等的位置为:%d\n",KMP(s,p,0));
 	return 0;
}

在这里插入图片描述

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值