Sunday算法

Sunday算法的思想跟BM算法很相似,不过Sunday采用模式匹配的思想,在匹配失败的时候关注的是主串中参加匹配的最末尾字符的下一位字符。

平均性能的时间复杂度为O(n)
最差情况的时间复杂度为O(n * m)

#include

using namespace std;

int main(void)
{
	string source = "Hello world,hello china,hello beijing", part = "china";
	int index = 0, i = 0, j = 0, next = 0;//index 主要用来记录每一次的匹配位置 i 每一次新的循环起始位置 j用来记录子串的遍历位置,next记录下一个起始位置
	while (i < source.length())
	{
		next = i + part.length();
		index = i;
		j = 0;
		if (part[j] != source[index])
		{
			//重新计算i的下一个位置
			if (next < source.length())
			{
				int cut = 0;
				for (int z = 0; z < part.length(); z++)if (source[next] == part[z])cut = z;
				if (cut == 0 && source[next] != part[0])next++;
				else next -= cut;
			}
			i = next;
			continue;
		}
		else
		{
			while (j < part.length())
			{
				if (part[j] != source[index])
				{
					//重新计算i的下一个位置
					if (next < source.length())
					{
						int cut = 0;
						for (int z = 0; z < part.length(); z++)if (source[next] == part[z])cut = z;
						if (cut == 0 && source[next] != part[0])next++;
						else next -= cut;
					}
					i = next;
					break;
				}
				index++;
				j++;
			}
			if (j == part.length())break;
		}
	}
	if (j == part.length())cout << "找到了,位置是: " << index - j;
	else cout << "没找到";
}

匹配原理:
从前往后匹配:

  • 如果遇到不匹配情况判断母串 S参与匹配的最后一位的下一位字符,如果该字符出现在模板串 T 中,选择最右出现的位置进行对齐;
  • 否则直接跳过该匹配区域。

例子

S:substring searching
T:search

步骤1:
Sunday算法_第1张图片
第二个字符u!=e,则直接跳到末尾i处,判断i是否存在于模式串T中

步骤2:
此时发现i不存在于模式串T中,后移一位,继续判断。
Sunday算法_第2张图片

此时n!=s,则直接跳到末尾处,判断r是否存在于模式串T中

步骤3:
发现模式串T中存在r,则直接对其。
Sunday算法_第3张图片

你可能感兴趣的:(算法)