OJ练习13——T28 Implement strStr()

实现字符串strstr()的功能,即从母串中查找子串第一次出现的位置(序号),没有出现则返回-1.

【思路】

刚开始学c时就学到过这个例子。

不同之处在于,这里参数是string,处理起来要比char*简单。

【my code】

int strStr(string haystack, string needle) {
    if(needle=="")
        return 0;
    if(haystack.size()<needle.size())
        return -1;
    int i=0, j=0, k;
    for(i=0; i<=haystack.size()-needle.size(); i++)
    {
        k=i;
        j=0;
        while(j<needle.size())
        {
            if(haystack[k]==needle[j])
            {
                k++;j++;
            }
            else
                break;
        }
        if(j==needle.size()){
            return i;
        }
    }
    return -1;
}

【出现的问题】

1.输入("", "")和("abcd", ""),("a", "aaaa")的特殊情况都要考虑;

2.易错!——最外层for循环,i的范围应该在i<=haystack.size()-needle.size(),否则会发生越界,报错为:

time limit exceed(like this?)

一定要注意数组越界访问的问题!

【番外】

看到网上有用KMP实现的,复习一下。

1.求next的函数。

next的结果是保存了“下一步跳到哪个位置来比较”的数组,next的作用是子串“自匹配”,找到子串中重复的元素,这样母串与子串比较时,母串顺次遍历不回溯。

2.注意j=-1的情况,以及匹配不成功时,不是j=0,而是j=next[j],其余和上面思路一样。

3.发生了传说中的一个有意思的bug!

先把正确代码po出来——

【other code】

void getNext(string needle, int *next)
{
    int j=-1;
    int i=0;
    next[0]=-1;
    while(i<needle.size()-1)
    {
        if(j==-1||needle[i]==needle[j]){
            j++;
            i++;
            next[i]=j;
        }
        else
            j=next[j];
    }
}
int strStr(string haystack, string needle)
{
    int hlen = haystack.size();
    int nlen = needle.size();
    int *next=new int[nlen];
    getNext(needle, next);
    int i=0, j=0;
    while(i < hlen&&j<nlen)//碰到传说中的情况!!
    {
        if(j==-1|| haystack[i]==needle[j])
        {
            j++;
            i++;
        }
        else
            j=next[j];
    }
    if(j==nlen)
        return i-j;
    else
        return -1;
}

【高能预警】

当代码是这样的:

while(i < haystack.size()&&j<needle.size())

运行结果就会总是-1!!

因为.size()是无符号类型,j和它比较j会转换为无符号类型,但j在这里会等于-1!(next[0]=-1)

此时,j就是一个无符号的大数,永远不会==nlen。

所以在程序开始用两个int变量记住string的size是个明智的做法,而且还会减少每次输入xxx.size()的繁琐。

原文地址:https://www.cnblogs.com/ketchups-notes/p/4423978.html