从概念上讲,您可以使用滑动窗口来解决这里的问题。对于您的示例,您有一个大小为 3 的滑动窗口。
对于字符串中的每个字符,您将当前字符的子字符串和接下来的两个字符作为当前模式。然后将窗口向上滑动一个位置,并检查字符串的其余部分是否包含当前模式包含的内容。如果是,则返回当前索引。如果没有,请重复。
例子:
1010101101
|-|
所以,模式 = 101。现在,我们将滑动窗口前进一个字符:
1010101101
|-|
看看字符串的其余部分是否有101,检查每个3个字符的组合。
从概念上讲,这应该是解决此问题所需的全部内容。
编辑:我真的不喜欢人们只要求代码,但由于这似乎是一个有趣的问题,这是我对上述算法的实现,它允许窗口大小变化(而不是固定在 3,该函数只进行了简单的测试并省略了明显的错误检查):
function findPattern( $str, $window_size = 3) {
// Start the index at 0 (beginning of the string)
$i = 0;
// while( (the current pattern in the window) is not empty / false)
while( ($current_pattern = substr( $str, $i, $window_size)) != false) {
$possible_matches = array();
// Get the combination of all possible matches from the remainder of the string
for( $j = 0; $j < $window_size; $j++) {
$possible_matches = array_merge( $possible_matches, str_split( substr( $str, $i + 1 + $j), $window_size));
}
// If the current pattern is in the possible matches, we found a duplicate, return the index of the first occurrence
if( in_array( $current_pattern, $possible_matches)) {
return $i;
}
// Otherwise, increment $i and grab a new window
$i++;
}
// No duplicates were found, return -1
return -1;
}
应该注意,这当然不是最有效的算法或实现,但它应该有助于澄清问题并给出如何解决问题的简单示例。