Sunday Search算法

 

基本思路是:

首先,对ASCII的255个字符在一个字符数组中设置其出现的逆序位置,如A在ASCII中是65,如果一个子串是BBAC,则在字符数组中第64(65-1)的位置为,4-3=1;D未出现在子串中,字符数组第68个位置为-1。

然后,对字符串匹配,如果成功则退出;如果不成功,则从字符数组中,获取当前子串长度在目标串的下一个位置上的字符,如果是-1,说明子串没有这个字符,直接跳过子串长度+1个字符;如果不为-1,子串向后移动字符数组值个字符。

 

以下部分代码来自Hoverlees's Blog

Sunday Search是比KMP和BM算法更快的串搜索算法,而且原理非常简单易理解.
#include <string.h>
/**
 * Sunday Search算法C实现
 * @author Hoverlees http://www.hoverlees.com
 */
unsigned char* sunday_search(unsigned char* str,int str_len,unsigned char* sub,int sub_len);

#include "sunday_search.h"

unsigned char* sunday_search(unsigned char* str,int str_len,unsigned char* sub,int sub_len){
	int marks[256];
	int i,j,k;
	unsigned char *ret=NULL;
	for(i=0;i<256;i++){
		marks[i]=-1;
	}
	if(str_len==-1) str_len=strlen(str);
	if(sub_len==-1) sub_len=strlen(sub);
	j=0;
	for(i=sub_len-1;i>=0;i--){
		if(marks[sub[i]]==-1){
			marks[sub[i]]=sub_len-i;
			if(++j==256) break;
		}
	}
	i=0;
	j=str_len-sub_len+1;
	while(i<j){
		for(k=0;k<sub_len;k++){
			if(str[i+k]!=sub[k]) break;
		}
		if(k==sub_len){
			ret=str+i;
			break;
		}
		k=marks[str[i+sub_len]];
		if(k==-1) i=i+sub_len+1;
		else i=i+k;
	}
	return ret;
}
#include <stdio.h>
#include <stdlib.h>
#include "sunday_search.h"

void main(int argc,char* argv[]){
	int i;
	//字符串测试
	char* src="hoverlee hehe xixi asdfasdfadfasdfashoverleesdi1294871-2alsdkjfzafsd hoverlees";
	char* sub="hoverlees";
	char* r=sunday_search(src,-1,sub,-1);
	if(r) printf("%s\n",r);
	else printf("not found\n");
	//内存块测试
	src=(char*) malloc(8196000);
	srand(1234567);
	for(i=0;i<8196000;i++){
		src[i]=rand()%256;
	}
	sub=(char*) malloc(1024000);
	for(i=0;i<1024000;i++){
		sub[i]=src[1234567+i];
	}
	r=sunday_search(src,8196000,sub,1024000);
	if(r) printf("%d\n",r-src);
	else printf("not found\n");
	free(src);
	free(sub);
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值