字符指针在简单的Boyer-Moore实现中出错

Character pointers messed up in simple Boyer-Moore implementation

本文关键字:实现 出错 Boyer-Moore 指针 简单 字符      更新时间:2023-10-16


我目前正在试验一种非常简单的Boyer-Moore变体
一般来说,我的实现是可行的,但如果我试图在循环中使用它,那么包含草堆的字符指针就会出错。我的意思是,里面的字符被改变了,或者混合了
结果是一致的,即多次运行相同的测试会产生相同的错误。

这是循环代码:

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;

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

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个匹配
  2. eedle!不用说,只需要找到2个匹配
  3. 没必要说eed 2会被发现的

正如您所看到的,在第二次运行后,输入完全混乱。我错过了什么?我认为内容无法修改,因为我正在传递const指针
在循环中设置指针的方式是错误的,还是我的字符串搜索搞砸了?

Btw:这是完整的代码,除了includes和围绕循环代码的主要函数。

编辑:

第一个返回的缺少nullptr是由于复制/粘贴错误,在源中它实际上就在那里。

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

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());
}

boyerMoore()函数中,第一个返回不是返回值(您只有return;而不是return nullptr;(GCC并不总是警告丢失的返回值,不返回任何内容都是未定义的行为。这意味着,当您将返回值存储在res中并再次调用该函数时,不知道会打印出什么。你可以在这里看到相关的讨论。

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