Leetcode 28 - 实现 strStr():问题
Posted
技术标签:
【中文标题】Leetcode 28 - 实现 strStr():问题【英文标题】:Leetcode 28 - Implement strStr(): question 【发布时间】:2019-08-06 14:51:07 【问题描述】:我在提交 Leetcode 28 时遇到了一个迄今为止我一直没有发现的错误。我的代码适用于大多数测试用例,但我对诸如 haystack = "mississippi", needle = "issip" 等场景感到困惑。
我尝试过调试,发现整个 haystack 字符串都被迭代了,它返回 -1 或未找到。它在每次出现“i”时找到的子字符串长度为 4、1、1。
int strStr(string haystack, string needle)
if (needle.empty())
return 0;
if (haystack.empty() && !needle.empty())
return -1;
int i = 0, j = 0, ans = 0;
for (i; i < haystack.length(); i++)
if (haystack[i] == needle[0])
j = 0;
ans = i;
for (j; j < needle.length(); j++)
/*
if (haystack[i++] == needle[j])
continue;
else
break;
*/
if (haystack[i++] != needle[j])
break;
if (j == needle.length())
return ans;
if (j == needle.length())
return ans;
return -1;
输入:“mississippi”、“issip” 输出:-1(ans = 10,j = 1)
【问题讨论】:
与您的问题无关,但您的第二个if
无缘无故地过于复杂。如果needle
不为空,则无需再次检查。
也许您应该解释一下,为什么haystack.find(needle)
不是您问题的答案?您可能有人为的限制,但请列出它们。
你看到haystack[i++]
的副作用了吗?您是否看到它如何跳过您的for (i;...
循环中的扫描规律?您对“整个 haystack 字符串进行迭代”的断言是错误的。
是的,限制是这样的,所以我想主要手动编写解决方案,除了非常简单的方法,例如 empty() 和 length()。另外,我没有重新格式化这个问题,所以会有冗余;我主要关心的是为什么会发生这个特定的错误。非常感谢!
【参考方案1】:
这个函数有几个缺点。
对于初学者来说,它应该被声明为
std::string::size_type strStr( const std::string &haystack, const std::string &needle );
如果在第一个字符串中没有找到第二个字符串,函数应该返回std::string::npos
,就像类 std::string 的所有类似成员函数一样。
函数参数shell是常量引用类型。
if 语句中的条件
if (haystack.empty() && !needle.empty())
有一个冗余操作数。它可以重写为
if (haystack.empty())
这个循环
for (i; i < haystack.length(); i++)
当第一个字符串尾部的大小小于第二个字符串的大小时,应该停止它的迭代。
在这个 if 语句中
if (haystack[i++] != needle[j])
变量 i 递增,导致变量递增两次:一次在此语句中,第二次在循环中。
这些语句的第二对
if (j == needle.length())
return ans;
是多余的。
这个函数可以写成如下演示程序所示。
#include <iostream>
#include <string>
std::string::size_type strStr( const std::string &haystack, const std::string &needle )
if ( needle.empty() )
return 0;
else if ( haystack.empty() )
return -std::string::npos;
else
std::string::size_type ans = std::string::npos;
auto n1 = haystack.length();
auto n2 = needle.length();
for ( std::string::size_type i = 0; ans == std::string::npos && i + n2 <= n1; i++ )
std::string::size_type j = 0;
while ( j < n2 && haystack[i+j] == needle[j] ) j++;
if ( j == n2 ) ans = i;
return ans;
int main()
std::string haystack( "mississippi" );
std::string needle( "issip" );
std::cout << strStr( haystack, needle ) << '\n';
return 0;
它的输出是
4
【讨论】:
【参考方案2】:问题是你在
中修改了iif (haystack[i++] != needle[j])
从而阻止探索第二个潜在匹配。试试
if (haystack[i + j] != needle[j])
并修复任何连锁问题。不过,我希望它能够按原样工作。
【讨论】:
啊,我明白了! i 在发生后续匹配后递增。非常感谢,这对我不会再犯同样的错误很有帮助。 现在,要记住的是,继续前进,这是您的算法。 O(n*m)(草垛和针长的乘积)。可能足以通过这个 leetcode。但是,如果您想完善它并了解更多信息,请查看 Boyer-Moore 算法,对于 O(n+m) 谢谢,我注意到这是非常低效的 (O(n*m))。我已经知道了 Knuth-Morris-Pratt,但我也会去看看 Boyer-Moore!以上是关于Leetcode 28 - 实现 strStr():问题的主要内容,如果未能解决你的问题,请参考以下文章
leetcode 28. Implement strStr() 实现strStr()