我正在尝试理解代码解决方案来查找字符串中第一个出现的索引问题。我在网上找到了这段代码,但我可以很好地把我的头包在两个ifs语句行:
如果(针[j]!==干草堆[i + j])断裂;
如果(j + 1 ===针长)
有人能把它分解一下吗?
let strStr = (haystack, needle) => {
// we loop through the first string
for (let i = 0; i < haystack.length; i++) {
// we loop through the second string
for (let j = 0; j < needle.length; j++) {
if (needle[j] !== haystack[i + j]) break;
if (j + 1 === needle.length) {
return i
}
}
}
return -1
};
strStr('sadbutsad', 'sad')
2条答案
按热度按时间qnakjoqk1#
为了理解代码的作用,首先需要理解
break
语句:break
将退出 closest/nearest 循环,即缩进最多的循环:现在,对于您的代码,2个
for
语句逐个字符地迭代2个字符串:haystack 和 needle。让我们给予这些字符串一些值,以便更好地解释:第一个for(使用变量
i
)逐字符遍历 haystack,对于每个索引i
,它尝试将 needle 字符串与 haystack 字符串的某个部分进行匹配,从索引i开始:第二个
for
实际上是逐个字符地比较字符串中对齐的部分是否相等,这次是逐个字符地比较 needle 字符串,首先,我们需要比较 haystack 中索引为6的字符(“w”)和 needle 中索引为0的字符(也是“w”):如果这个相等失败,我们停止整个比较(这是第二次,使用
j
变量,使用break
语句),接下来,我们在j=1时再次这样做:现在,我们需要对比两个(分别在2个字符串中的索引7和1处)。为了得到7,我们添加
i + j
,并且为了得到1,我们仅使用j
。最后,如果我们检查所有字符并且它们都匹配,我们要报告“成功”(我们通过返回 haystack 中的索引i
来实现,在该索引处我们匹配了 needle)如果到达最后一个字符,我们知道我们完成了对所有字符的检查,即needle.length - 1
(因为长度5意味着索引0-4;last index is 4 = 5-1).这是if
检查的内容--是否到达最后一个字符.如果到达,则意味着break
语句从未执行过,因此没有一个字符不匹配.jchrr9hc2#
所以这段代码实际上 * 做的 * 是查看字符串
haystack
,并返回haystack
中的子字符串needle
的开头的字符索引,如果有的话。if (needle[j] !== haystack[i + j]) break;
在上下文中,i
是haystack的子字符串的开始,当前正在测试它是否与needle相同。内部循环j
检查needle和haystack的每个字符,以查看它们是否相同。“needle”总是从零开始,因为您正在查看整个字符串,所以你使用needle[j]
。“haystack”从i
开始,因为有外循环,所以它使用haystack[i+j]
。如果这些字符不匹配,那么你的内循环知道它找到了和needle不同的东西,所以中断并继续外循环的下一次迭代。if (j + 1 === needle.length) return i
更容易解释:如果needle有三个字符长,那么只需要检查三个字符,由于它们都匹配(我们知道这一点是因为前面的条件没有break
),那么我们就知道我们已经在干草堆中找到了needle,并且可以返回它的初始索引。(This严格地说,是不必要的,因为内部循环I无论如何都要在那个点结束(因为
j
只迭代到needle.length
),所以不用if
语句,你可以在内部循环之后简单地使用return i
:如果你到达那个点而没有突破,你就知道你有一场完整比赛。我怀疑包含这一行只是为了让它更明确,并且在教学环境中更容易理解代码。就我个人而言,有时候我会故意包含这样的“不必要”代码,如果它让函数更容易理解的话,尽管在这种情况下,代码注解也会起作用。
你给出的例子的结果是0,但是如果不是简单的例子,解释一下会更好一些,比如“haystack”包含“xyzababcdxyz”,“needle”是“abcd”。
i
将从0开始,j
将从0开始,needle[j]
是“a”,并且haystack[i+j]
是“x”。它们不相等,因此将中断;对于i=1和i=2也是如此。在
i=3
上,事情变得更加有趣。内部循环再次从零开始。
needle[j]
是needle[0]
是“a”。haystack[i+j]
是haystack[3+0]
是“a”。这匹配,所以我们继续i=3,j=1,并得到needle[1]
和haystack[4]
,它们再次匹配(“B”)。所以我们继续i=3,j=2,这是needle[2]
与haystack[5]
的比较,但是它们不匹配(“c”和“a”)。所以我们再次跳出内部循环,再次递增i
。i=4,j=0不匹配,所以我们立即中断。
在i=5时,我们又开始看到匹配,这一次,遍历
needle
的整个长度,没有发现不匹配,所以我们知道可以返回i
作为输出。