#include<iostream>
using namespace std;
//匹配字符串。能匹配子串在原始字符串中所有出现的位置的开始下标,下标以0开始。
int match(int i, int n, const char *ori, const char *sub)
{
int j;
for (j = 0; j < n; j++)
{
if (ori[i] == sub[j])
{
if (j == n - 1)
{
cout << "the position is " << i - j << endl;
return 1;
}
i++;
}
else
{
return 0;
}
}
}
void sunday(const char *ori,const char *sub)
{
int m, n, i=0, flag,j;
m = strlen(ori);
n = strlen(sub);
while (i<m)
{
//关键点,必须放在这里,总共两种情况,一种是原始字符串ori的i+n+1处的字符在子串sub里面,一种是ori的i+n处的字符不在子串sub里面
//前者:若子串sub在第其j个位置匹配到ori的i+n处的字符,则将sub串第j位置移动到ori的i+n处,相当于从ori串的i+n处向前数j个数,这个位置
//就是ori指针i应该移动到的位置;
//后者,若子串sub匹配不到ori的i+n处的字符,说明sub串没有该字符,则ori指针i跳转到i+n+1位置在开始匹配
int flag1 = 0; //第一种情况必须要执行,若第一种不满足,则就第二种情况
if ((flag = match(i, n, ori, sub)) == 0)
{
for (j = n - 1; j >= 0; j--) //第一种情况
{
if (ori[i + n] == sub[j])
{
i = i + n - j;
flag1 = 1;
break;
}
}
if (flag1 == 0) //第二种情况
{
i = i + n + 1;
}
}
else
{
i = i + n; //这样可以进行多次匹配,找出所有匹配的位置。原理:当匹配完一次后,将ori指针i移到i+n处
//break; //这样只能进行一次匹配。原理:匹配完后就直接退出循环了。
}
}
}
int main()
{
char src[] = "subsearchstring secrchsearching";
char des[] = "search";
sunday(src, des) ;
return 0;
}
sunday算法大致思想:当发现失配的时候就判断子串的后一位在母串的字符是否在子串中存在?如果存在则将该位置和子串中的该字符对齐,在从头开始匹配。如果不存在就将子串向后移动,和子串的后一位在母串的字符对齐,再进行匹配。重复上面的操作直到找到,或母串被找完结束。
转载他人的成果,万分感谢。其他算法介绍:
http://dsqiu.iteye.com/blog/1700312
http://blog.163.com/yangfan876@126/blog/static/80612456201342205056344/