简单的 字符串比较函数 易懂 复杂度

1.简单的字符串匹配函数

简单的字符串匹配很简单,就是一个两重循环。

算发一:

#include<stdio.h>

#include<string.h>

 

char s[51],t[11];

int next[11];

int cnt[11];

 

void index(char*s,char *t,int pos)

{

       int i,j,k;

    int x = 0;

    int len1 = strlen(s);

    int len2 = strlen(t);

 

    for(i=pos;i<len1;i++)

    {

        k = i;

        for(j=0;j<len2;j++)

        {           

            if(s[k++]!=t[j])

                break;

        }

        if(j>=len2)

        {

            cnt[x++] = i;

        }

    }

}

 

int main(void)

{

    memset(cnt,-1,11*sizeof(int));

    gets(s);

    gets(t);

    int pos;

    scanf(“%d”,&pos);

       index(s,t,pos);

    for(int i=0;cnt[i]!=-1;i++)

    {

        printf(”    %d”,cnt[i]);

    }

return 0;

}

下面分析其复杂度:  

《简单的 字符串比较函数 易懂 复杂度》

除了在index2,index4,index6,index10四处字符串比较了多次外,在其他地方字符串只比较了一次,总共的比较次数为(n-m+1)+(m-1)+others,others为红色的部分,也就是说其复杂度接近O(n+m)。

假设主串的长度为n,模式串的长度为m,在最坏情况下,对于主串(n-m+1)中的每一个字符,都要和模式中的字符匹配m次,后面的每个字符的匹配次数总共为(1+2+…+(m-1))=m(m-1)/2,则总的匹配次数为(n-m+1)*m+ m(m-1)/2,也即算发复杂度为O(n*m)。

 

  上面这种方法比较的直观和简单,但是复杂度却很高,效率低下,很难应用于实际,下面有个改进的版本,功能是输出第一次出现子串的索引。

算发二:

#include <stdio.h>

#include <string.h>

 

char s[51],t[11];

int next[11];

 

int index(char *s,char *t,int pos)

{

    int i =pos-1;

    int j = 0;

    int len1=  strlen(s);

    int len2 =strlen(t);

 

   while(i<len1&&j<len2)

    {

       if(s[i]==t[j])

        {

            i++;

            j++;

        }

        else

        {

            i -=j-1;

            j =0;

        }

    }

       if(j>=len2)

    {

       returni-len2;

    }

    else

       return-1;

}

 

int main(void)

{

    gets(s);

    gets(t);

    int pos;

   scanf(“%d”,&pos);

 

    int no =index(s,t,pos);

    if(no>0)

       printf(“String s contains substring t at index of %d~~\n”,no);

    else

       printf(“String s does not contain substring t~~\n”);

    return 0;

}

下面让我们来分析其复杂度,

《简单的 字符串比较函数 易懂 复杂度》

除了在index2,index4,index6,index10四处字符串比较了多次外,在其他地方字符串只比较了一次,假设最终查找到子串的位置为index,在一次查找过程中,最终的比较次数为(index+len2-1)+others,这个others就是之前有过的多次比较的结果。其复杂度接近O(n+m)。在最坏的情况下,其复杂度也是O(n*m)。

算发三:

#include <stdio.h>

#include <string.h>

 

char s[51],t[11];

int next[11];

int cnt[11];

 

void index(char *s,char *t,int pos)

{

   intx=0;

   int i = pos-1;

   int j = 0;

   int len1 =  strlen(s);

   int len2 = strlen(t);

 

   for(i=pos-1;i<len1;)

    {

       while(i<len1&&j<len2)

       {

           if(s[i]==t[j])

           {

                i++;

                j++;

           }

           else

           {

               i -= j-1;

               j = 0;

           }

       }

          if(j>=len2)

       {

          cnt[x++] = i-len2;

             i -= len2-1;

             j = 0;

       }

   }   

}

 

int main(void)

{

   memset(cnt,-1,11*sizeof(int));

   gets(s);

   gets(t);

   int pos;

   scanf(“%d”,&pos);

 

   index(s,t,pos);

  

   for(int i=0;cnt[i]!=-1;i++)

    {

       printf(”    %d”,cnt[i]);

    }

   printf(“\n”);

   return 0;

}

点赞