c++ - 字符指针在简单的 Boyer-Moore 实现中搞砸了

标签 c++ pointers


我目前正在试验一个非常简单的 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. 针!不用说,只需要找到 2 个匹配!
  3. 不用说,eed 2 一定会被发现!

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

顺便说一句:这是完整的代码,除了 includes 和围绕循环代码的 main 函数。

编辑:

第一个返回的缺失 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; 而不是 return nullptr;) GCC 并不总是警告缺少返回值,不返回任何东西是未定义的行为。这意味着当您将返回值存储在 res 中并再次调用该函数时,不知道会打印出什么。你可以看到一个 related discussion here .

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

关于c++ - 字符指针在简单的 Boyer-Moore 实现中搞砸了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32332791/

相关文章:

c++ - 如何在编译时找出 integer_sequence 是否包含给定的数字?

c# - 非得用C#dll调用C++dll?

c++ - 在 C++ 中访问预定义 float 组时出现问题

C-在执行过程中检查特定的内存地址

c - C 中的函数是否有 "type name"?

c++ - 我需要使值可修改

c++ - 如何在 qt 中禁用 QComboBox 的快捷方式?

c++ - opengl 3.3 核心配置文件渲染失败

c++ - 函数指针作为映射参数时出错? C++

c++ - 将项目推送到 STL 容器后出现段错误