Horspool算法

一、算法思想

空间换时间

把模式Pattern和文本Text的开头字符对齐,从模式的最后一个字符开始比较,如果尝试比较失败了,把模式向后移。向后移动的距离是查已构造好的移动表获得。每次尝试过程中比较是从右到左的。
移动表的构造可以仅使用模式串Pattern,设字符c是文本Text中对齐模式串的最后一个字符的元素,那么在每次匹配失败时,就根据字符c查找移动表来确定移动距离(不管字符c和模式串的最后一个字符是否匹配)。对于每个字符c,可用以下公式算出移动距离:
在这里插入图片描述

二、代码
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
//构造移动表(仅构造了模式串中存在的字符,模式串中不存在的字符移动距离为模式串长度)
unordered_map<char,int> buildTable(string& partern){
	unordered_map<char,int> moveTable;
	int m = partern.size();
	for(int i=0;i<m-1;++i){
		moveTable[partern[i]] = m-1-i;  
	}
	return moveTable;
}
//Horspool字符串匹配. 返回第一个匹配子串最左端字符的下标 or -1
int Horspool(string& partern,string& text){
	unordered_map<char,int> moveTable = buildTable(partern);
	int m = partern.size(), n = text.size();
	int i = m-1; 
	while(i<n){
		int k = 0;  //匹配字符的个数
		//从右向左进行匹配
		while(k<m && partern[m-1-k]==text[i-k]){
			k+=1;   
		}
		if(k==m){//模式全部匹配成功
			return i-m+1;
		}
		else{ //否则根据移动表进行移动
			i = moveTable.find(text[i])!=moveTable.end() ? i+moveTable[text[i]] : i+m;
		}
	}
	return -1;
}
三、KMP算法

KMP算法

vector<int> getNext(string& partern){
	int n = partern.size();
	vector<int> next(n);
	next[0] = -1;
	int j = 0,k = -1;
	while(j < n-1){
		if(k == -1 || partern[j] == partern[k]){
			next[++j] = ++k;
		}
		else{
			k = next[k];
		}
	}
	return next;
}

int kmp(string& partern,string& text){
	int i = 0;  //主串的位置
	int j = 0;  //模式串的位置
	int n = text.size(),m = partern.size();
	vector<int> next = getNext(partern);
	while(i<n && j<m){
		if(j == -1 || text[i] == partern[j]){ //当j为-1时,要移动的是i,j也要归0
			i++;
			j++;
		}
		else{
			j = next[j];
		}
	}
	if(j==m){
		return i-j;
	}
	else {
		return -1;
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值