串的模式匹配
串的模式匹配就是从一个主串中找到子串出现的位置,如主串是"asd234",子串是"d2",那么算法返回的结果就应该是2.
一种最朴素的想法就是BF算法,我就不讲了," 最朴素"嘛,就是你脑子里现在想的那种算法.
比较优一点的是KMP算法.
更优的是BM算法.
BM的改进算法是Sunday Algorithm.
现在我给出BF和Sunday两种算法的代码,然后再和STL中string在find函数进行比较.
STL中string在find函数示例:
string name("AnnaBelle");
string::size_type pos=name.find("Anna"); //pos==0
#include<iostream> #include<cstring> #include<ctime> using namespace std; int BF(const string &str1,const string &str2){ int len1=str1.size(); int len2=str2.size(); int i=0; int j=0; while(i<len1 && j<len2){ if(str1[i]==str2[j]){ i++; j++; } else{ i+=1-j; j=0; } } if(j==len2) return i-j; else return -1; } int findChar(const string &str,char c){ int len=str.size(); for(int i=len-1;i>=0;i--){ if(str[i]==c){ return i; } } return -1; } int Sunday(const string &str1,const string &str2){ int len1=str1.size(); int len2=str2.size(); int i=0; int j=0; int begin=i; while(i<len1 && j<len2){ if(str1[i]==str2[j]){ i++; j++; } else{ int index=findChar(str2,str1[begin+len2]); if(index<0){ begin+=len2+1; j=0; i=begin; } else{ int ps=len2-index; begin+=ps; j=0; i=begin; } } } if(j==len2) return i-j; else return -1; } int main(){ const int N=1000000; string str1,str2; cout<<"Input MainString: "; getline(cin,str1); cout<<"Input SubString: "; getline(cin,str2); clock_t start,finish; start=clock(); for(int i=0;i<N;i++) BF(str1,str2); finish=clock(); cout<<"BF:"<<BF(str1,str2)<<"\t"<<(double)(finish-start)/CLOCKS_PER_SEC<<"s"<<endl; start=clock(); for(int i=0;i<N;i++) Sunday(str1,str2); finish=clock(); cout<<"Sunday:"<<Sunday(str1,str2)<<"\t"<<(double)(finish-start)/CLOCKS_PER_SEC<<"s"<<endl; start=clock(); for(int i=0;i<N;i++) str1.find(str2); finish=clock(); cout<<"STL:"<<str1.find(str2)<<"\t"<<(double)(finish-start)/CLOCKS_PER_SEC<<"s"<<endl; return 0; }
下面是两个测试用例:
STL总是出奇地快,Sunday并不是总比最笨的BF算法快.
本文来自博客园,作者:高性能golang,转载请注明原文链接:https://www.cnblogs.com/zhangchaoyang/articles/2025245.html