【问题标题】:own implementation of std::string::find (brute-force search)自己的 std::string::find 实现(蛮力搜索)
【发布时间】: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”更好的名称

标签: c++ string algorithm implementation brute-force


【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-02-23
      • 2021-01-08
      • 1970-01-01
      • 2017-10-22
      • 2015-02-20
      • 2012-05-24
      • 2021-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多