串的模式匹配算法(BF算法和KMP算法)
BF算法(Brute Force Algorithm),也称为朴素模式匹配算法(Naive Pattern Matching Algorithm),是一种简单直观的串的模式匹配算法。
BF算法的基本思想是从文本串中的每一个可能的起始位置开始,逐个比较模式串和文本串中对应位置的字符,以确定是否匹配。具体步骤如下:
从文本串的第一个字符开始,逐个字符地与模式串的对应字符比较。
如果所有字符都匹配,则找到了模式串在文本串中的一个匹配位置。
如果字符不匹配,则文本串的匹配位置向后移动一位,继续与模式串比较,直至找到匹配位置或者遍历完文本串。
//串的模式匹配 (BF算法)
#include<stdio.h>
#include<string.h>
void brteForce(char*pattern,char*text){
int patternLength=strlen(pattern);
int textLength=strlen(text);
for(int i=0;i<=textLength-patternLength;i++){
int j;
for(j=0;j<patternLength;j++){
if(text[i+j]!=pattern[j])
break;
}
if(j==patternLength)
printf("找到模式串的索引是%d\n",i);
}
}
int main(){
char text[]="aabaacaadaabaaba";
char pattern[]="aaba";
printf("模式%s\n",pattern);
printf("文本%s\n",text);
brteForce(pattern,text);
return 0;
}
BF算法的优点是简单易懂,容易实现,但在处理大规模文本串时,效率较低。因为它的时间复杂度最坏情况下为O((n-m+1)*m),其中n是文本串的长度,m是模式串的长度。因此,在实际应用中,对于大规模文本串的模式匹配,可能会选择使用更高效的模式匹配算法,如KMP算法、Boyer-Moore算法或Rabin-Karp算法等。
KMP算法(Knuth-Morris-Pratt算法)是一种高效的字符串匹配算法,用于在一个文本串中查找一个模式串的出现位置。
其基本思想是利用模式串自身的特点,在匹配过程中通过预处理模式串,构建一个部分匹配表(Partial Match Table,PMT),利用该表在匹配过程中减少不必要的比较次数,从而提高匹配效率。
KMP算法的关键在于构建部分匹配表
,该表记录了模式串中每个位置的最长相等前缀和后缀的长度。在匹配过程中,当出现不匹配的情况时,根据部分匹配表的信息,将模式串相对于文本串向右移动尽可能远的距离,避免了不必要的字符比较。
代码如下
#include<stdio.h>
#include<string.h>
//计算模式串的最长前缀后缀(longest prefix suffix)数组
void computeLPSArray(char*pattern,int patternLength,int*lps){
int len=0;
lps[0]=0;
int i=1;
while(i<patternLength){
if(pattern[i]==pattern[len]){
len++;
lps[i]=len;
i++;
}
else{
if(len!=0){
len=lps[len-1];
}
else{
lps[i]=0;
i++;
}
}
}
}
//KMP算法的主要函数,用于在文本中搜索模式串的出现位置
void KMPSearch(char*pattern,char*text){
int patternLength=strlen(pattern);
int textLength=strlen(text);
int lps[patternLength];
computeLPSArray(pattern,patternLength,lps);
int patternIndex=0;
int textIndex=0;
while(textIndex<textLength){
if(pattern[patternIndex]==text[textIndex]){
patternIndex++;
textIndex++;
}
if(patternIndex==patternLength){
printf("在索引处找到模式%d\n",textIndex-patternIndex);
patternIndex=lps[patternIndex-1];
}
else if(textIndex<textLength&&pattern[patternIndex]!=text[textIndex]){
if(patternIndex!=0)
patternIndex=lps[patternIndex-1];
else
textIndex++;
}
}
}
int main(){
char text[]="AABAACAADAABAABA"; //待搜索的文本
char pattern[]="AABA"; //待匹配的模式
printf("文本:%s\n",text);
KMPSearch(pattern,text);
return 0;
}
KMP算法的时间复杂度为O(n+m),其中n是文本串的长度,m是模式串的长度。相对于BF算法等朴素的模式匹配算法,KMP算法在大规模文本串中的模式匹配具有更高的效率和性能优势。
感谢阅读