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

own implementation of std::string::find (brute-force search)

本文关键字:搜索 实现 std string find 自己的      更新时间:2023-10-16

我试图在字符串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;
        }
    }
}

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

在这一部分中:

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,对吧?:)

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

  • 将函数参数更改为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;
}