字符串匹配暴力匹配法和KMP匹配算法对比

暴力匹配算法和KMP 算法比较:

算法实现:

#include

#include

#include//使用fstream中定义的类及各种成员函数

#include

#include

#include //时间函数

using namespace std; //开辟内存空间

int strStr(char* haystack,char* needle) //暴力算法

{

  if(haystack==NULL||needle==NULL)//判断主串和副串是否为空

              return-1;

   const int len_h=strlen(haystack);//求主串的长度

   const int len_n=strlen(needle);

   for(int i=0;i长度小于副串一定找不到

       {

       int j=0;

       for(j=0;j

              {

           if(haystack[i+j]!=needle[j]) //每个字符比较

                     {

                break;

           }

       }

       if(j==len_n)

                     returni;

    }

       return-1;

}

 

void cal_next(char* source,int* next,intlen)//next的函数(KMP

{

   next[0]=-1;           //next[0]初始化为-1-1表示不存在相同的最大前缀和最大后缀

   int k=-1;             //k初始化为-1

   for(int q=1;q <= len-1; q++)

    {

       while (k > -1 && source[k + 1] != source[q])

              //如果下一个不同,那么k就变成next[k],注意next[k]是小于k的,无论k取任何值。

       {

           k = next[k];                  //往前回溯

       }

       if (source[k + 1] == source[q])//如果相同,k++

       {

           k = k + 1;

       }

       next[q] = k;//这个是把算的k的值(就是相同的最大前缀和最大后缀长)赋给next[q]

    }

}

int KMP(char *source, int slen, char*target, int plen)

{

   int *next = new int[plen];

   cal_next(target, next, plen);//计算next数组

   int k = -1;

   for (int i = 0; i < slen; i++)

    {

       while (k >-1&& target[k + 1] != source[i])

              //targetsource不匹配,且k>-1(表示targetsource有部分匹配)

           k = next[k];                   //往前回溯

       if (target[k + 1] == source[i])

           k = k + 1;

       if (k == plen-1)              //说明k移动到target的最末端

       {                                      

           return i-plen+1;         //返回相应的位置

       }

    }

   return -1; 

}

int main()//主函数入口

{

       fstreamoutfile;

       outfile.open("f3.txt",ios::out);//以写的方式打开文件

       if(!outfile)//判断文件是否为空

{

              cout<<"f3.txtcan't open.\n";

              abort();

       }

       //生成随机数

       inti;

       srand((unsigned)time(NULL));//它初始化随机种子,会提供一个种子,这个种子会对应一个随机数,如果使用相同的种子后面的rand()函数会出现一样的随机数

      

for(i=0;i<10000;i++){

        char ch=rand()%26+'a';//产生az的小写字母

        outfile<写进文件

    }

       fstreaminfile;

       infile.open("f3.txt",ios::in);//读文件

       if(!infile){

              cout<<"f3.txtcan't open.\n";

              abort();

       }

       chars1[10000];

    while(!infile.eof())//一直读字符,直到读到完

        {

          infile.getline(s1,sizeof(s1));

        }

   infile.close();//关闭文件

       char  *source=s1;

    char * target="ab";

    cout<<"主串是:"<主串

    cout<<"要查找的字符串是:"<副串

   int i1=strlen(source);//求字符串长度

   int j1=strlen(target);

      

 

       clock_tstart,finish;//时间函数

       doubletotaltime;

       start=clock();

       inta = KMP(source,i1, target,j1);//传参函数调用

              for(intd=0;d<10000000;d++){KMP(source,i1, target,j1);}

     if(a==-1)

         cout<<"字符串不匹配"<

         else 

                cout<<"从第"<个字符开始匹配"<

       finish=clock();

       totaltime=(double)(finish-start)/CLOCKS_PER_SEC;

       cout<<"kmp程序的运行时间为"<  s"<

      

       clock_tstart1,finish1;//时间结束

       doubletotaltime1;

       start1=clock();

      

   

 

   int b;

       b=strStr(source,target);

       for(intc=0;c<10000000;c++){strStr(source,target);}

       if(b==-1)

       cout<<"字符串不匹配"<

       else

              cout<<"从第"<个字符开始匹配"<

       finish1=clock();

       totaltime1=(double)(finish1-start1)/CLOCKS_PER_SEC;

       cout<<"暴力程序的运行时间为"<!"<

       return0;

}

 

 

输出结果:

两个算法比较分析:

经计算,暴力匹配算法易知其时间复杂度:o(n-m)*m,而KMP 算法时间复杂度为: o(n+m),两种算法同时在C++同一个编译器下多次执行,首先从运行结果和时间复杂度上,KMP算法都比暴力算法好很多,暴力匹配算法虽然能解决问题,但是在效率上差的很远,暴力匹配算法无论是在代码量还是在处理问题上,都没有KMP算法高效, KMP算法的精髓在于不必要以主串种每一个元素下标为首都比一边,而是建立了next,以巧妙地算法跳过了不可能匹配的字符串,所以在字符数量较大的情况下构造过程比较复杂,KMPnext数组构造就快多了,所以KMP算法要比暴力匹配算法好

你可能感兴趣的:(字符串匹配暴力匹配法和KMP匹配算法对比)