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;
}