【leetcode】Implement strStr

题目

仅对这个题而言,用普通的方法,就是所谓的BF,相信大家都能够实现,区别只是谁的代码更简练,但是实现的算法都是一样的,这里写写KMP,至于kmp前前后后的来龙去脉,这里不做讲解,自认为还没这个能力,在走访过的博客论坛技术贴中,也未曾清楚的明白作者所言为何物,这里没有贬低的意思,每个作者将自己明白和理解的东西能无私的分享出来,都是非常棒的!

这里给 大家提供几个讲解KMP的链接,是能够跟着走一遍就能明白的那种。

1. 阮一峰:字符串的KMP算法

2.相似的英文博客:jBoxer

看了这两篇文章,如果不用你自己生成next表,估计现在你可以很快的写出kmp算法,并能讲解清楚。下面看看维基百科里给出的匹配算法和生成next表的伪代码。维基:Knuth-Morris-Pratt algorithm

//kmp search pseudo code

伪代码:

algorithm kmp_search:
    input:
        an array of characters, S (the text to be searched)
        an array of characters, W (the word sought)
    output:
        an integer (the zero-based position in S at which W is found)

    define variables:
        an integer, m ← 0 (the beginning of the current match in S)
        an integer, i ← 0 (the position of the current character in W)
        an array of integers, T (the table, computed elsewhere)

    while m + i < length(S) do
        if W[i] = S[m + i] then
            if i = length(W) - 1 then
                return m
            let i ← i + 1
        else
            if T[i] > -1 then
                let i ← T[i], m ← m + i - T[i]
            else
                let i ← 0, m ← m + 1
            
    (if we reach here, we have searched all of S unsuccessfully)
    return the length of S

//build next table

algorithm kmp_table:
    input:
        an array of characters, W (the word to be analyzed)
        an array of integers, T (the table to be filled)
    output:
        nothing (but during operation, it populates the table)

    define variables:
        an integer, pos ← 2 (the current position we are computing in T)
        an integer, cnd ← 0 (the zero-based index in W of the next 
character of the current candidate substring)

    (the first few values are fixed but different from what the algorithm 
might suggest)
    let T[0] ← -1, T[1] ← 0

    while pos < length(W) do
        (first case: the substring continues)
        if W[pos - 1] = W[cnd] then
            let cnd ← cnd + 1, T[pos] ← cnd, pos ← pos + 1

        (second case: it doesn't, but we can fall back)
        else if cnd > 0 then
            let cnd ← T[cnd]

        (third case: we have run out of candidates.  Note cnd = 0)
        else
            let T[pos] ← 0, pos ← pos + 1

实现代码

按着伪代码我们试着实现一下。仅供参考。

void fill_table(string p, vector<int>& table)
{
	table[0] = -1;
	table[1] = 0;
	int index = 2;
	int cnt = 0;
	while (index < p.size())
	{
		if(p[cnt] == p[index - 1])
			p[index++] = ++cnt;

		else if(cnt > 0)
			cnt = table[cnt];

		else
			table[index++] = 0;	
	}
}

int Compare(string s, string p)
{
	if(s.size() < p.size() || s.size() == 0 || p.size() == 0)
		return s.size();

	int m = 0;
	int i = 0;
	vector<int> table(p.size() + 1,0);
	fill_table(p, table);

	while (m + i < s.size())
	{
		if(i >= p.size()) return m;
		
		if(s[m + i] == p[i]) ++i;
		else{
			m += i - table[i];
			i = 0;
		}
	}
	return s.size();
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值