LeetCode-实现Strstr

题解

双指针法

  这道题是字符串匹配问题,第一反应当然是KMP算法和BF算法,虽然前两天刚学了KMP,自己动手写还是不会写next数组。按自己思路写了双指针算法,虽然提交通过,但是代码质量极差可以称为垃圾代码…,运行时间1960ms…

#include "iostream"
#include "string"
using namespace std;
class Solution {
public:
	int strStr(string haystack, string needle) {
	    if(needle.length()==0||needle==haystack)return 0;
	    if(needle.length()>haystack.length())return -1;
	    int i;
	    for(i=0;i

库函数法

  偷个懒,调函数。

#include "iostream"
#include "string"
using namespace std;
class Solution {
public:
	int strStr(string haystack, 	string needle) {
	    if(needle.empty())	return 0;
	    else
	    {
	        int 	pos=haystack.find	(needle);
	        return pos;
	    }
	    return -1;
	}
};   

BF算法

  暴力解法,但比我的代码高效的多,匹配成功时,各自+1,比较下一位。匹配失败下标就要回溯,对于needle串,要回溯到0的位置,对于Haystack串,则返回到i-j+1的位置。

#include "iostream"
#include "string"
using namespace std;
class Solution {
public:
	int strStr(string haystack, string needle) {
        //加几个很好想到的特殊情况,加快判断
        if(needle.empty() || needle==haystack )	return 0;
        if(needle.length()>haystack.length())	return -1;

        int i=0,j=0;
        while(needle[i]!='\0' 	&& haystack[j] !='\0')
        {
            if(needle[i]	==haystack[j])
            {
                i++;
                j++;
            }
            else  //回溯
            {   
                //haystack从上次匹配的下一位开始 needle从头开始
	            j=j-i+1;
	            i=0;
	        }
	    }
	    if(needle[i]=='\0')	return j-i;
	    else return -1;
	}
};

KMP算法

class Solution {
public:
	vector getnext(string str)
	    {
	        int len=str.size();
	        vector next;
	        next.push_back(-1);//next数组初值为-1
	        int j=0,k=-1;
	        while(j next;
	    next=getnext(needle);
	    while((i

KMP算法next数组优化

  next数组可以进行优化,当字符失配时,回到相同字符无意义,应继续递归。

 vector getnext(string str)
    {
        int len=str.size();
        vector next;
        next.push_back(-1);//next数组初值为-1
        int j=0,k=-1;
        while(j

  以下几种算法来自

https://leetcode-cn.com/problems/implement-strstr/solution/c5chong-jie-fa-ku-han-shu-bfkmpbmsunday-by-2227/

的总结,还没有很理解,先收藏进来。

BM算法

class Solution {
public:
void get_bmB(string& T,vector& bmB)//坏字符
{
    int tlen=T.size();
    for(int i=0;i<256;i++)//不匹配直接移动子串
    {
        bmB.push_back(tlen);
    }
    for(int i=0;i& suff)
{
    int tlen=T.size();
    int k;
    for(int i=tlen-2;i>=0;i--)
    {
        k=i;
        while(k>=0&&T[k]==T[tlen-1-i+k])
            k--;
        suff[i]=i-k;
    }
}

void get_bmG(string& T,vector& bmG)//好后缀
{
    int i,j;
    int tlen=T.size();
    vector suff(tlen+1,0);
    get_suff(T,suff);//suff存储子串的最长匹配长度
    //初始化 当没有好后缀也没有公共前缀时
    for(i=0;i=0;i--)
        if(suff[i]==i+1)
            for(j=0;j bmG	(tlen,0);
    	vector bmB;
    	get_bmB(needle,bmB);
    	get_bmG(needle,bmG);
    
    	while(i<=slen-tlen)
    	{
        	for(j=tlen-1;j>-1&&haystack[i+j]==needle[j];j--);
	        if(j==(-1))
            return i;
	        i+=max(bmG[j],bmB[haystack[i+j]]-	(tlen-1-j));
	    }
	    return -1;
	}
};

Sunday

class Solution {
public:
	int strStr(string haystack, string needle) {
    	if(needle.empty())
    	    return 0;
    	
    	int slen=haystack.size();
    	int tlen=needle.size();
    	int i=0,j=0;//i指向源串首位 j指向子串首位
    	int k;
    	int m=tlen;//第一次匹配时 源串中参与匹配的元素的下一位
    
    	for(;i=0;k--)//遍历查找此时子串与源串[i+tlen+1]相等的最右位置
    	        {
    	            if(needle[k]==haystack[m])
    	                break;
            }
    	        i=m-k;//i为下一次匹配源串开始首位 Sunday算法核心:最大限度跳过相同元素
    	        j=0;//j依然为子串首位
    	        m=i+tlen;//m为下一次参与匹配的源串最后一位元素的下一位
    	        if(m>slen)//当下一次参与匹配的源串字数的最后一位的下一位超过源串长度时
    	            return -1;
    	    }
    	    else
    	    {
    	        if(j==tlen-1)//若j为子串末位 匹配成功 返回源串此时匹配首位
    	            return i-j;
    	        i++;
    	        j++;
    	    }
    	}
    	return -1;//当超过源串长度时 
	}
};

你可能感兴趣的:(LeetCode-实现Strstr)