2013-06-05 61 views
1

如何對[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)) 

期望: 從草堆匹配針的鍵。上述應該給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'; 
     } 
    } 
} 
+0

乾草堆的每個元素都是單個字符嗎? –

+0

這是一個有點太具體的內置函數。你能向我們展示一些你試圖自己寫的代碼嗎?否則,這只是你要求代碼的一個例子,這並不是真正的 – Pudge601

+1

啊,這是一個有限狀態自動機的美好例子。 –

回答

2

我試圖創建這個功能;

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 
     ) 

) 
+0

謝謝 - 這似乎工作...我認爲我可以按照邏輯#(代碼看起來很簡單 - 但對於我的生活,我無法找到休息等等 - 再次,謝謝!) – theclueless1

+0

否問題=]傑克的答案與我的相比是非常令人滿意的簡潔,但是這個優點是數組的值可以是任何類型的,比如對象等。 – Pudge601

+0

好吧 - 我不是100%肯定的,但我認爲Jacks的速度會稍微快一點......但都很好 - 謝謝Pudge601和Jack – theclueless1

3

如果草堆由字母,您可以在此做串域:

$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); 
+0

這個工作,但我真的希望有一個更靈活的解決方案,其中乾草堆不是由單個字母,但可能是字母串。 –

+0

@STTLCU你不是操作系統:) –

+0

@傑克 - 我看到作品...我會用一些其他的價值測試它(因爲它可能包含多於單身)::謝謝:D – theclueless1