BF算法
利用独特的回潮机制,以穷举的思想进行匹配算法
当主串与模式串匹配中,出现不匹配的情况时,主串指针i回潮到上一次起点的下一个数据项处,而模式串的指针j,则返回模式串的起点位,而后二者同时进行位置上的向后平移操作,进行BF算法的匹配
代码实现(C语言)
#include<stdio.h>
#include <windows.h>
int main(){
int i=0,j=0;
int sum=0;
int into=0;
char arr[10] = "dasdfghjki";
char arr1[5] = "dfghj";
LARGE_INTEGER t1, t2, tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&t1);
for(i=0,j=0;i<=9&&j<=4;){
if(arr[i] == arr1[j]){
sum++;
i++;
j++;
}else if(arr[i] != arr1[j]){
into++;
sum=0;
j=0;
i=into;
}
if(sum==5){
printf("找到了!\n");
break;
}
}
QueryPerformanceCounter(&t2);
printf("程序耗时:%lf微秒\n",(double)(t2.QuadPart-t1.QuadPart)/(double)tc.QuadPart);
return 0;
}
算法优点:逻辑简单易懂,代码可读性高
算法缺点:时间复杂度是远远比不上KMP算法优秀的
KMP算法
在BF算法的基础上,人们认为BF算法过于笨重和局限,为了追求极致的运算速率,节约时间成本,KMP算法应运而生。
利用已经匹配的数据项结果,来作出预处理,以人为的预运算,来节约机器运算时间,从而达到时间效率的提升
当主串数据项与模式串数据项匹配失败时,主串指针i将不再回潮到上一次起始位置的下一个数据项位置,模式串指针也不再回潮到起始位置,而是由人为的对已知成功匹配长度内所有数据项的可能出现的断点位置进行预处理,从而使主串与模式串已匹配数据项进行预匹配,从而减少数据项重复匹配次数,以此提升时间效率
代码实现(C语言)
#include<stdio.h>
#include <windows.h>
int main(){
int i=0,j=0;
int sum = 0;
char arr[10] = "dfgdfghjki";
char arr1[5] = "dfghj";
LARGE_INTEGER t1, t2, tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&t1);
for(i=0,j=0;i<=9&&j<=4;){
if(arr[i] == arr1[j]){
sum++;
i++;
j++;
}else if(arr[i] != arr1[j]){
j=0;
sum=0;
}
if(sum==5){
printf("找到了!\n");
break;
}
}
QueryPerformanceCounter(&t2);
printf("程序耗时:%lf微秒\n",(double)(t2.QuadPart-t1.QuadPart)/(double)tc.QuadPart);
return 0;
}
算法优点:大大提高了时间效率,减少了计算机的算力负荷
算法缺点:提升了编程人员的代码编程难度,从而拉升了编程人员算法书写的能力门槛
总结:
在本次实验中,大家看完后可能会觉得,只是把时间效率提升了一倍而已,这种提升不够惊艳。
但是这两种算法当然不是仅仅提升一倍效率这么简单,下面是本次两种算法的最坏时间复杂度对比
从这里可以看到,仅仅提升一倍效率的原因,绝不是算法本身的原因。
而是我这一次实验中的对比数组中的数据项基数过小的原因,我仅仅只是用了十个数据项与五个数据项进行匹配,从整体算力产生的时间损耗上,仅仅只是微秒级的差距。
而从两者的时间复杂度中可以看出,当匹配的两者数据项基数足够大时,两者所产生的时间差距,理论上可以达到无穷大比上无穷小的结果,那时间基数的对比将是不可估量的!
所以本次实验的目的,本来就是我自己想体会一下两种算法的时间效率的差距,从代码层面上将会有多少不同,而现在在仅仅只是改变了几行代码的情况下,提升了如此之多的时间成本,让我真真认识到了FMP算法的价值!
希望本次实验,对于读到最后的你有所帮助。