【问题标题】:Find array in array, in sequence在数组中按顺序查找数组
【发布时间】:2013-06-05 15:15:23
【问题描述】:

如何编写[find-array-in-array] 函数?

伪代码

干草堆

array(0=a, 1=b, 2=a, 3=b, 4=c, 5=c, 6=a, 7=b, 8=d, 9=c, 10=a, 11=b, 12=a, 13=b, 14=c);

array(a, b, c);

返回

array ( array (2, 3, 4), array(12, 13, 14) )

希望: Haystack 中与 Needle 匹配的钥匙。以上应该给出2个匹配项:

  1. 比赛 = 干草堆 2-4
  2. 比赛 = 干草堆 12-14

它应该找不到"a b""a b d""c a b" 等, Needle 中每个值的唯一实例 - 以指定的顺序。

我想让它成为一个函数,这样我就可以重复运行它(我有很多这样的模式)。

我试过用嵌套的 foreachs 来做这件事,并用计数器等把自己逼疯了。 我到了一定程度,无法将匹配项与非匹配项区分开来。 (惊讶于没有内置函数?in_arrayarray_intersect 似乎只用于单个值,而不是集合?)


$haystack = array('a','b','a','b','c','d','a','b','c');
$needle = array('a','b','c');

$CountH = count($haystack); echo $CountH."<br/>";
$CountN = count($needle); echo $CountN."<br/>";
$matches ='';
foreach ($haystack as $key1=>$haystackval){
    foreach ($needle as $key2=>$needleval) {
        $fail = '0';
        //if (in_array($needleval, $haystack)) {
        if ($key2[$needleval] === $haystackval && $fail === '0') {
            echo "Got needleval - ".$needleval ."<br/>";
        } 
        else { $fail='1';
        }
    } 
}

【问题讨论】:

  • 大海捞针的每个元素都是一个字符吗?
  • 这有点过于具体,无法作为内置函数。您能向我们展示一些您尝试自己编写的代码吗?否则,这只是您要求代码的情况,而这并不是 SO 的真正用途
  • 啊,有限状态自动机的一个很好的例子。
  • @Pudge601 - 我会为你更新。
  • @Jack - 不,它的范围可能从单个字符到 20 个字符......因此你可以看到“a bbbbbbbbb ccccc dddddddddddddddddddd”

标签: php arrays


【解决方案1】:

我尝试创建这个函数;

function find_array_in_array($needle, $haystack) {
    $keys = array_keys($haystack, $needle[0]);
    $out = array();
    foreach ($keys as $key) {
        $add = true;
        $result = array();
        foreach ($needle as $i => $value) {
            if (!(isset($haystack[$key + $i]) && $haystack[$key + $i] == $value)) {
                $add = false;
                break;
            }
            $result[] = $key + $i;
        }
        if ($add == true) { 
            $out[] = $result;
        }
    }
    return $out;
}

$haystack = array('a', 'b', 'a', 'b', 'c', 'c', 'a', 'b', 'd', 'c', 'a', 'b', 'a', 'b', 'c');

$needle = array('a', 'b', 'c');

print_r(find_array_in_array($needle, $haystack));

输出;

Array
(
    [0] => Array
        (
            [0] => 2
            [1] => 3
            [2] => 4
        )

    [1] => Array
        (
            [0] => 12
            [1] => 13
            [2] => 14
        )

)

【讨论】:

  • 谢谢 - 这似乎有效......我想我可以遵循逻辑#(代码看起来很简单 - 但对于我的生活来说,我无法想象休息等 - 再次,谢谢!)
  • 没问题 =] 诚然,与我的相比,Jack 的回答相当简洁,但这个的优点是数组值可以是任何类型,例如对象等。跨度>
  • 嗯 - 我不是 100% 确定,但我认为 Jacks 的速度稍微快了一点......但两者都很棒 - 谢谢 Pudge601 和 Jack
  • 由于灵活性而被选为答案
  • @Pudge601 你是天才!
【解决方案2】:

如果干草堆由字母组成,您可以在字符串域中这样做:

$haystack = array('a', 'b', 'a', 'b', 'c', 'c', 'a', 'b', 'd', 'c', 'a', 'b', 'a', 'b', 'c');
$haystack = join('', $haystack);

preg_match_all('/abc/', $haystack, $matches, PREG_OFFSET_CAPTURE);

print_r(array_map(function($item) {
  return range($item[1], $item[1] + strlen($item[0]) - 1);
}, $matches[0]));

输出:

Array
(
    [0] => Array
        (
            [0] => 2
            [1] => 3
            [2] => 4
        )

    [1] => Array
        (
            [0] => 12
            [1] => 13
            [2] => 14
        )

)

大海捞针中可能有多个字符,您需要求助于:

$haystack = array('a', 'b', 'a', 'b', 'c', 'c', 'a', 'b', 'd', 'c', 'a', 'b', 'a', 'b', 'c');
$needle = array('a', 'b', 'c');

// cache array sizes
$haystack_len = count($haystack);
$needle_len = count($needle);

// shortlist the possible starting keys
$possible_keys = array_keys($haystack, $needle[0], true);

$results = array();

foreach ($possible_keys as $index) {
    // start searching
    $i = $index; $j = 0;
    while ($i < $haystack_len && $j < $needle_len) {
        if ($haystack[$i] !== $needle[$j]) {
            continue 2; // no match
        }
        ++$i; ++$j;
    }
    // match
    $results[] = range($index, $index + $needle_len - 1);
}

print_r($results);

【讨论】:

  • 这行得通,但我真的希望有一个更灵活的解决方案,干草堆不是由单个字母组成,而是由字母串组成。
  • @STTLCU 虽然你不是 OP :)
  • @Jack - 我看到这行得通......我会用其他一些值来测试它(因为它可能包含多个单曲):: 谢谢:D
  • @theclueless1 我已更新我的答案以包含多个字符。
  • @Jack - 再次感谢您!我正在打印匹配的结果 - Array ( [0] => Array ( [0] => Array ( [0] => a b c [1] => 4 ) [1] => Array ( [0] = > a b c [1] => 24 ) ) ) ... 我喜欢看到搜索到的字符串(触感很好),但数字似乎翻了一番?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多