2012-06-11 3 views
-3

У меня есть массив в PHPPHP, некоторые эффективные алгоритмы

$arr = array(
    array('id' => 1, 'par' => 5), 
    array('id' => 2, 'par' => 5), 
    array('id' => 3, 'par' => 5), 
    array('id' => 4, 'par' => 7), 
    array('id' => 5, 'par' => 7), 
    array('id' => 6, 'par' => 7), 
    array('id' => 7, 'par' => 9), 
    array('id' => 8, 'par' => 9), 
    ... 
); 

Может кто-нибудь знает эффективный алгоритм, чтобы получить первые Indeks элемента, который имеет свойство $ обр [х] [п '] = = 7. Как получить первый x из массива, содержащего 2000 элементов?

Спасибо

+0

Какой код вы пытался решить эту проблему? – Haroon

+0

Всегда ли они в порядке возрастания? Если это так, на ум приходит двоичный алгоритм поиска. – Jay

+0

Я попробовал двоичный код, но потребовалось больше времени, чем линейный алгоритм. – iff

ответ

0

Я использовал бинарный поиск

$par = 7; 
$a = 0;$i = -1; 
$b = count($arr); 
while(true) { 
    if($par == $arr[$a]['par']) { $i = $a; break; } 
    if($par == $arr[$m]['par']) { $i = $m; break; } 
    if($par == $arr[$b]['par']) { $i = $b; break; } 
    if($a == $m || $m == $b) break; 
    if($arr[$a]['par'] < $par && $par < $arr[$m]['par']) { 
     $b = $m; $m = floor(($a+$b)/2); 
    } 
    if($arr[$m]['par'] < $parent && $parent < $arr[$b]['par']) { 
     $a = $m; $m = floor(($a+$b)/2); 
    } 
} 

Этот пример был более медленным, чем $ я = 0, в то время как ($ я < $ п & & $ обр [$ я] ['par']! = $ par) $ i ++; Может ли использоваться array_search?

0

Я не уверен, что при использовании итератора быстрее, чем делать это с помощью «руки», но вы можете использовать RecursiveArrayIterator - http://php.net/manual/en/class.recursivearrayiterator.php

$arr = array(
    array('id' => 1, 'par' => 5), 
    array('id' => 2, 'par' => 5), 
    array('id' => 3, 'par' => 5), 
    array('id' => 4, 'par' => 7), 
    array('id' => 5, 'par' => 7), 
    array('id' => 6, 'par' => 7), 
    array('id' => 7, 'par' => 9), 
    array('id' => 8, 'par' => 9), 
); 

$arrayIterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); 
foreach ($arrayIterator as $subKey=>$subValue) { 
     if ($subKey == 'par' && $subValue == 9) { 
       $validArray = iterator_to_array($arrayIterator->getSubIterator()); 
       $id = $validArray['id']; // This is your return array 
       break; 
     } 
} 

Но, честно говоря, делать это вручную будет вероятно, будет намного легче понять и отлаживать, а для 2000 записей - зачем с чем более сложным, чем:

foreach($arr as $subArray) { 
    if ($subArray['par'] == 9) { 
      $id = $subArray['id']; 
      break; 
    } 
} 

Если вы обработки больше записей, или имели популярность Facebook, а затем начинают серьезно. Но иногда поддерживать его просто - это лучший способ.

+0

. Я сравнивал также данные RecursiveIteratorIterator и RecursiveArrayIterator с линейным, но также более медленным, чем линейно. Может ли кто-нибудь дать лучший пример? – iff

+0

Помимо написания исходного массива правильно (т. Е. С использованием ассоциативного массива с парами ключ/значение), то простой способ, вероятно, все же ваш самый быстрый. – Robbie

Смежные вопросы