自己的 std::string::find 实现(蛮力搜索)

Posted

技术标签:

【中文标题】自己的 std::string::find 实现(蛮力搜索)【英文标题】:own implementation of std::string::find (brute-force search) 【发布时间】:2013-09-08 03:33:41 【问题描述】:

我正在尝试在字符串P 中查找字符串T 的出现并返回TP 中的位置。

这是我尝试过的,但不正确:

int bruteForce(string T, string P) 
    int n, m;
    for (int i = 0; i <= n-m; i++) 
        int j = 0;
        while (j < m && T[i+j] == P[j]) 
            if (j == m) 
                return i;
            
            return 0;
        
    

我做错了什么?我错过了什么?

【问题讨论】:

首先,您使用了从未初始化过的变量nm 坏了,n,m 没有初始化。您的代码将调用 UB 您是否尝试实现T.find(P) 你正在复制你被调用的字符串。您可能想要“const string& T, const string& P)”,但您可能应该使用比“T”和“P”更好的名称 【参考方案1】:

在这部分:

int n,m;
for (int i=0;i<= n-m;i++) 

您正在使用导致未定义行为的未初始化局部变量。也尝试用比字母更有意义的东西来命名你的变量,我认为你的真正意思是:

int bruteForce(std::string needle, std::string haystack) 
    int needleLen = needle.length(),
        haystackLen = haystack.length();
    for (int i = 0; i <= needleLen - haystackLen; i++) 
        int j = 0;
        while (j < haystackLen && needle[i+j] == haystack[j]) 
            if(j == haystackLen) 
                return i;
            
            return 0;
        
    
    // return 0;  <-- 

还请注意,如果needle[i+j] 都不等于haystack[j](对于每个i),则在您的函数中return 没有任何值。 needle 是 "ab" 和 haystack 是 "aab" 的情况怎么样~> 在比较 needle[1]haystack[1] 时,你的函数会 return 0 (它应该放在 for 循环之后)

另一个合理的更改是将按值传递更改为按引用传递以避免创建副本。由于你的函数不会改变这些字符串,它的原型应该是:

int bruteForce(const std::string& needle, const std::string& haystack)

如果您不想故意创建自己的std::string::find 实现,但由于某种原因,您仍然需要在失败时将它用于return 0(您是否考虑过在needle 相等时使用您的函数到haystack?) 它可能看起来像这样:

std::size_t bruteForce(const std::string& needle, const std::string& haystack) 
    std::size_t pos = haystack.find(needle);
    if (pos != std::string::npos)
        return pos;
    return 0;

...但如果是这种情况,您不会称它为bruteForce,对吗? :)

【讨论】:

【参考方案2】:

我尽量不要过多地更改您的代码。我的更改是:

将函数参数更改为const reference 以避免浪费复制。 变量nm 未初始化。 内部while 循环有问题。它没有增加 j 并且成功的测试在循环之外更有意义。 失败的返回值不能是0,因为这可能是一个有效的位置。

修改后的代码(经过简单测试,似乎可以工作):

int bruteforce(const std::string &T, const std::string &P)

    int n = T.length();
    int m = P.length();
    for (int i = 0; i <= n-m; ++i) 
        int j = 0;
        while (j < m && T[i+j] == P[j]) 
            ++j;
        
        if (j == m)  // match found
            return i;
        
    
    return -1;

【讨论】:

以上是关于自己的 std::string::find 实现(蛮力搜索)的主要内容,如果未能解决你的问题,请参考以下文章

不区分大小写的 std::string.find()

不区分大小写的 std::string.find()

std::string::find 返回值问题

C++ std::string::find()函数(在字符串中查找内容)

C++中std::string::find_last_of用法

C++ std::string::find_first_of()函数(在字符串中搜索与其参数中指定的任何字符匹配的第一个字符)