字符串匹配算法之sunday算法

// 【04】StringMatch-Sunday.cpp : Defines the entry point for the console application.
//  字符串匹配算法之sunday算法

#include "stdafx.h"
#include "string.h"
#include "iostream"

using namespace std;

#define MAX_CHAR_SIZE 256

int* SetCharStep(const char* pattern);
int StrMatch_BruteForce(const char* text, const char* pattern, int* CharStep);
int StrMatch_Sunday(const char* text, const char* pattern, int* CharStep);

int _tmain(int argc, _TCHAR* argv[])
{
	char* text = "this is uestc,welcome to our school!";
	char* pattern = "wel";

	int* CharStep = SetCharStep(pattern);
	cout<<StrMatch_Sunday(text, pattern, CharStep)<<endl;

	delete CharStep;
	CharStep = NULL;

	while(true);

	return 0;
}

int StrMatch_Sunday(const char* text, const char* pattern, int* CharStep)
{
	int m=0, n=0, s=0, step=0;//	m: 模型长度,n: 文本长度	s:有效匹配位置  step:移动步长
	
	m = strlen(pattern);
	n = strlen(text);

	if(m > n)
		return -1;
	else
	{
		while(s <= (n-m))					//	匹配结束条件
		{
			//	开始匹配
			//	如果匹配,返回当前有效位置值S。如果不匹配,找当前文本中最右边对齐的右一位的那个字符在模式串的位置,
			//	然后结束本次循环,开始下一次匹配。
			step = StrMatch_BruteForce(text+s, pattern, CharStep);
			if(0 == step)
				return s;
			else
			{
				s += step;
			}
		}
		return -1;
	}
}

//	匹配成功返回0
int StrMatch_BruteForce(const char* text, const char* pattern, int* CharStep)
{
	int m=0, n=0;

	m = strlen(pattern);
	n = strlen(text);

	for(int i=0; i<m; i++)
	{
		if( *(text+i) != *(pattern+i) )		//	匹配失败,返回当前文本中最右边对齐的右一位的那个字符在模式串的位置
		{
			return CharStep[(unsigned char)text[m]];
		}
	}
	return 0;
}

//	预处理:事先存储好需要移动的步长
int* SetCharStep(const char* pattern)
{
	int* pCharStep = new int[MAX_CHAR_SIZE];
	int m=strlen(pattern);

	//memset(pCharStep, 0, sizeof(pCharStep));
	//之所以默认初始化每个字符的步长为m+1,是因为如果文本中当前对齐右边的字符不在子串中时,要跳过该字符,即移动步长为m+1
	for(int i=0; i<MAX_CHAR_SIZE; i++)
		pCharStep[i] = m+1;

	//	注意从左向右扫描一遍 保存子串中每个字符所需移动步长
	for(int i=0; i<m; i++)
	{
		pCharStep[(unsigned char)pattern[i]] = m-i;
	}
	return pCharStep;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值