字符匹配之KMP算法

                                                                                                    KMP字符串匹配算法
        该算法只与模式串(字串)有关。BF算法匹配会造成很多没有必要的回溯。kmp算法就是避免这些没有必要的回溯。
        当模式串主串匹配到某个位置的时候失配,假设该模式串下标为j,主串下标为i,则模式串下标0~j-1都是匹配的,按照BF算法,我们要将模式串回溯到首位,主串回溯到第二位重新匹配。
        情况一:
                如果模式串完全没有相同的元素,则前面匹配的全匹配,而模式串之间没有相同的元素,回溯过去也不可能匹配
                例如:
                        i l o v e T H i o v e T H K
                        i l o v e T H K
                        此时,i与Q失配,如果仅回溯一位
                        i l o v e T H i o v e T H K
                          i l o v e T H Q
                        不可能匹配,我们完全可以直接回溯到i与K来匹配
                        i l o v e T H i l o v e T H K
                                           i l o v e T H K
        情况二:
               如果模式串有相同的元素,也有不必要的回溯。
               例如:
                        w w w x h h
                        w w x
                        此时w与x失配,不能按照情况一,直接将1号元素来与失配元素匹配。而是
                        w w w x h h
                            w w x

按照KMP算法来解答:
       回溯的时候不是直接一位一位的回溯,而是按照next数组的指导来回溯。
       求next数组:
              TS串:模式串与主串失配位置前的元素就是TS串。
              TC串:TS串能自从后包含(即从后面往前看也是匹配的)TC串(TC串是TS串的字串),TC串的第一个字符是模式串的第一个字符。TC短于TS。TC可能不为1
              此时的next数组的第n个元素激素该n对应下的|TC|+1;
              注意,为了保证不丢失可能的匹配情况,必须选择最长的TC串。
                     求TC串:
                            先求出TS,分为TS1,TS2,将TS1设为主串,TS2为模式串,一步一步右移TS2,判断竖着相对应的元素是否完全相等,相等的就是最长TC串。
                            例:
                            TS1:A B A
                            TS2:    A B A
                            -->
                            TS1:A B A
                            TS2:        A B A
                            -->
                            TC=A
                            next[4]=|TC|+1=2

        C++实现源码:

#include <iostream>
#include <string>

class FstringASstring{
	public:
		std::string Fs;//主串(父串) 
		std::string Ss;//模式串 (子串) 
		int *next;
		int *nextVal;
		
		FstringASstring();
		bool KMP();
		void getNext();
		void getNextVal();
};

int main(){
	FstringASstring FAS;
	if(FAS.KMP()){
		std::cout<<"Ss是Fs的子字符串!\n";
	}else{
		std::cout<<"Ss不是Fs的子字符串!\n";
	}
	return 0;
}

FstringASstring::FstringASstring(){
	Fs="abcdefg";
	Ss="defg";
	next=new int(Ss.length());
	nextVal=new int(Ss.length());
}

void FstringASstring::getNext(){
	int indexS=0;//索引TS串中字符 
	int indexC=-1;//索引TC串中字符 
	
	next[0]=-1;
	
	while(indexS<Ss.length()-1){
		if(indexC==-1    //TC串与TS串完全没有重合,跳转到模式串的第一位去 
			//TC:1...indexC
			//TS:1...indexS
			//TC与TS最大重合了,next[indexS+1]就有结果了 
		||Ss[indexS]==Ss[indexC]){
			++indexC;
			++indexS;
			next[indexS]=indexC;
		}else{
			indexC=next[indexC];//利用已得的next,对TC串进行跳转 
		}
	}
}

bool FstringASstring::KMP(){
	getNextVal();
	int i=0;//主串下标
	int j=0;//模式串下标
	
	while(i<(int)Fs.length() && j<(int)Ss.length())
	{
		if(j==-1 || Fs[i]==Ss[j])
		{
			i++;
			j++;
		}else
		{
			j=nextVal[j];
		}
	} 
	
	if(j == (int)Ss.length())
	{
		return true;
	}
	else
	{
		return false;
	}
}

void FstringASstring::getNextVal(){
	int indexS=0;//索引TS串中字符 
	int indexC=-1;//索引TC串中字符 
	
	nextVal[0]=-1;
	
	while(indexS<Ss.length()-1){
		if(indexC==-1    //TC串与TS串完全没有重合,跳转到模式串的第一位去 
			//TC:1...indexC
			//TS:1...indexS
			//TC与TS最大重合了,next[indexS+1]就有结果了 
		||Ss[indexS]==Ss[indexC]){
			++indexC;
			++indexS;
			
			//跳转后的字符,与当前字符不同,则找最终跳转到 位置
			if(Ss[indexS]!=Ss[indexC]){
				nextVal[indexS]=indexC;
			} 
			else{
				//nextVal[indexC]已经求得了
				nextVal[indexS]=nextVal[indexC];	
			}
		}else{
			indexC=nextVal[indexC];//利用已得的next,对TC串进行跳转 
		}
	}
}
资源下载链接为: https://pan.quark.cn/s/9e7ef05254f8 在网页设计中,为图片添加文字是一种常见的需求,用于增强视觉效果或传达更多信息。本文将介绍两种常用的方法:一种是将图片设置为背景并添加文字;另一种是利用<span>标签结合CSS定位来实现。 这种方法通过CSS实现,将图片设置为一个容器(通常是<div>)的背景,然后在容器中添加文字。具体步骤如下: 创建一个包含文字的<div>元素: 使用CSS设置<div>的背景图片,并调整其尺寸以匹配图片大小: 如有需要,可使用background-position属性调整图片位置,确保文字显示在合适位置。这样,文字就会显示在图片之上。 另一种方法是将文字放在<span>标签内,并通过CSS绝对定位将其放置在图片上。步骤如下: 创建一个包含图片<span>标签的<div>: 设置<div>为相对定位,以便内部元素可以相对于它进行绝对定位: 设置<span>为绝对定位,并通过调整topleft属性来确定文字在图片上的位置: 这种方法的优点是可以精确控制文字的位置,并且可以灵活调整文字的样式,如颜色字体大小。 两种方法各有优势,可根据实际需求选择。在实际开发中,还可以结合JavaScript或jQuery动态添加文字,实现更复杂的交互效果。通过合理运用HTMLCSS,我们可以在图片上添加文字,创造出更具吸引力的视觉效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值