首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单Boyer-Moore实现中的字符指针混乱

简单Boyer-Moore实现中的字符指针混乱
EN

Stack Overflow用户
提问于 2015-09-01 13:21:20
回答 1查看 74关注 0票数 0

我目前正在试验一种非常简单的Boyer变体。

一般来说,我的实现可以工作,但是如果我试图在循环中使用它,包含干草堆的字符指针就会被搞砸。我的意思是里面的字符是被改变的或者是混合的。

结果是一致的,即运行相同的测试多次产生相同的错误。

这是循环代码:

代码语言:javascript
复制
string src("This haystack contains a needle! needless to say that only 2 matches need to be found!");
string pat("needle");
const char* res = src.c_str();

while((res = boyerMoore(res, pat)))
    ++res;

这是我实现的字符串搜索算法(上面的代码调用了一个方便的包装器,它提取字符串的字符指针和长度):

代码语言:javascript
复制
unsigned char*
boyerMoore(const unsigned char* src, size_t srcLgth, const unsigned char* pat, size_t patLgth)
{
    if(srcLgth < patLgth || !src || !pat)
        return nullptr;

    size_t skip[UCHAR_MAX]; //this is the skip table
    for(int i = 0; i < UCHAR_MAX; ++i)
        skip[i] = patLgth; //initialize it with default value

    for(size_t i = 0; i < patLgth; ++i)
        skip[(int)pat[i]] = patLgth - i - 1; //set skip value of chars in pattern

    std::cout<<src<<"\n"; //just to see what's going on here!

    size_t srcI = patLgth - 1; //our first character to check
    while(srcI < srcLgth)
    {
        size_t j = 0; //char match ct
        while(j < patLgth)
        {
            if(src[srcI - j] == pat[patLgth - j - 1])
                ++j;
            else
            {
                //since the number of characters to skip may be negative, I just increment in that case

                size_t t = skip[(int)src[srcI - j]];
                if(t > j)
                    srcI = srcI + t - j;
                else
                    ++srcI;
                break;
            }
        }
        if(j == patLgth)
            return (unsigned char*)&src[srcI + 1 - j];
    }
    return nullptr;
}

循环产生这个输出(即,这些是算法接收到的干草堆):

  1. 这干草堆里有一根针!不用说,只需要找到两个匹配!
  2. 伊德尔!不用说,只需要找到两个匹配!
  3. 无缘无故地说,两次相遇都是为了被发现!

如您所见,输入在第二次运行后完全混乱。我遗漏了什么?我认为内容无法修改,因为我传递的是const指针。

是在循环中设置指针的方式出错了,还是我的字符串搜索搞砸了?

顺便说一句:这是完整的代码,除了包含和循环代码的主要功能。

编辑:

第一次返回的nullptr缺失是由于复制/粘贴错误造成的,在源中它实际上是存在的。

为了澄清这一点,这是我的包装函数:

代码语言:javascript
复制
inline char* boyerMoore(const string &src, const string &pat)
{
    return (const char*) boyerMoore((const unsigned char*) src.c_str(), src.size(),
            (const unsigned char*) pat.c_str(), pat.size());
}
EN

回答 1

Stack Overflow用户

发布于 2015-09-01 14:08:26

在您的boyerMoore()函数中,第一个返回不是返回一个值(您只有return;而不是return nullptr;) GCC并不总是对丢失的返回值发出警告,而不返回任何东西是未定义的行为。这意味着,当您将返回值存储在res中并再次调用该函数时,不知道将输出什么。你可以看到一个related discussion here

此外,您还省略了计算要传入的字符串长度的方便函数。我建议对逻辑进行二次检查,以确保大小是正确的--我假设您使用的是strlen或类似的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32332791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档