За последние 24 часа нас посетили 59356 программистов и 7105 роботов. Сейчас ищут 2357 программистов ...

Поиск ближайших значений в массиве

Тема в разделе "Прочие вопросы по PHP", создана пользователем dsda, 21 июл 2009.

  1. dsda

    dsda Активный пользователь

    С нами с:
    3 сен 2008
    Сообщения:
    34
    Симпатии:
    0
    Подскажите алгоритм поиска ближайших значений массива по отношению к заданному.

    Тоесть есть массив
    Код (Text):
    1. for ($x=0;$x<=99;$x++) { $arr[]=rand(1,100); }
    и значение допустим 50 и надо найти элемент массива к значению которого эта переменная максимально близка.
     
  2. sylex

    sylex Активный пользователь

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
    dsda
    циклом перебор, простой алгоритм блин
     
  3. dsda

    dsda Активный пользователь

    С нами с:
    3 сен 2008
    Сообщения:
    34
    Симпатии:
    0
    это я понимаю. подскажите сам алгоритм. а то я что-то туплю =(
     
  4. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.254
    Симпатии:
    0
    Адрес:
    Київ
    Что тут тупить то?

    PHP:
    1. <?php
    2.  
    3. $arr = array();
    4. for ($x = 10; $x--;) {
    5.     $arr[] = rand(1,100);
    6. }
    7.  
    8. function searchNearest ($value, $inArray) {
    9.     $lastKey = null;
    10.     $lastDif = null;
    11.     foreach ($inArray as $k => $v) {
    12.         if ($v == $value) {
    13.             return $k;
    14.         }
    15.         $dif = abs ($value - $v);
    16.         if (is_null($lastKey) || $dif < $lastDif) {
    17.             $lastKey = $k;
    18.             $lastDif = $dif;
    19.         }
    20.     }
    21.     return $lastKey;
    22. }
    23. echo searchNearest(40, $arr), "\n";
    24. asort($arr);
    25. print_r($arr);
    26. ?>
    27.  
    28.  
    Код (Text):
    1. 2
    2. Array
    3. (
    4.     [5] => 17
    5.     [1] => 21
    6.     [4] => 30
    7.     [2] => 43
    8.     [8] => 49
    9.     [7] => 65
    10.     [0] => 76
    11.     [6] => 92
    12.     [9] => 97
    13.     [3] => 100
    14. )
    Код (Text):
    1. 8
    2. Array
    3. (
    4.     [9] => 1
    5.     [6] => 5
    6.     [3] => 11
    7.     [1] => 24
    8.     [8] => 53
    9.     [0] => 70
    10.     [7] => 72
    11.     [5] => 81
    12.     [4] => 84
    13.     [2] => 90
    14. )
    возвращает ключ массива, по которому ближайшее значение
     
  5. sylex

    sylex Активный пользователь

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
    PHP:
    1. <?php
    2.  
    3. $arr = array();
    4.  
    5. for ($x=0;$x<=29;$x++) { $arr[]=rand(1,100); }
    6.  
    7. print_r($arr);
    8.  
    9. $e = 50;
    10. $i = 0;
    11. $val = $arr[0];
    12. $z = abs($val-$e);
    13. foreach ($arr as $k => $v) {
    14.     $new = abs($v-$e);
    15.     if ($new<$z) {
    16.         $i = $k;
    17.         $val = $v;
    18.         $z = $new;
    19.     }
    20. }
    21.  
    22. echo "<br><br>poisk {$e} = index element {$i}, value {$val}";
     
  6. sylex

    sylex Активный пользователь

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
    TheShock
    у тебя более красиво :)
     
  7. kostyl

    kostyl Guest

    другое дело если массив отсортирован уже...
     
  8. dsda

    dsda Активный пользователь

    С нами с:
    3 сен 2008
    Сообщения:
    34
    Симпатии:
    0
    Спасибо большущее, буду разбираться что я неправильно делал.
     
  9. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.254
    Симпатии:
    0
    Адрес:
    Київ
    если массив отсортирован, то из массива длиной в 1'000'000 элементов достаточно получить 20 значений - это естественно. Но мы берем совершенно случайный массив ведь.

    sylex, спс :)
     
  10. kostyl

    kostyl Guest

    TheShock
    Дык я о чем и говорю может быстрей отсортировать и найти? Ну смотря какого размера массив и какие там данные...
     
  11. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.254
    Симпатии:
    0
    Адрес:
    Київ
    kostyl, сомневаюсь, что есть смысл, если честно.
     
  12. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.254
    Симпатии:
    0
    Адрес:
    Київ
    Нету смысла. Мой алгоритм быстрее сортировки:
    PHP:
    1. <?php
    2.  
    3. $arr = array();
    4. for ($x = 150000; $x--;) {
    5.     $arr[] = mt_rand(1,1000000);
    6. }
    7.  
    8. function searchNearest ($value, $inArray) {
    9.     $lastKey = null;
    10.     $lastDif = null;
    11.     foreach ($inArray as $k => $v) {
    12.         if ($v == $value) {
    13.             return $k;
    14.         }
    15.         $dif = abs ($value - $v);
    16.         if (is_null($lastKey) || $dif < $lastDif) {
    17.             $lastKey = $k;
    18.             $lastDif = $dif;
    19.         }
    20.     }
    21.     return $lastKey;
    22. }
    23. echo 'length     : ' , count($arr) , "\n";
    24.  
    25. // Searching key
    26. $s = microtime(1);
    27. echo 'key        : ', searchNearest(40, $arr), "\n";
    28. echo 'key search : ', (microtime(1) - $s), "\n";
    29.  
    30. // Sorting array
    31. $s = microtime(1);
    32. asort($arr);
    33. echo 'array sort : ', (microtime(1) - $s), "\n";
    34. ?>
    Код (Text):
    1. $ php -f searchNearest.php
    2.  length     : 150000
    3.  key        : 37331
    4.  key search : 0.189264059067
    5.  array sort : 0.320148944855
    6.  
    7. $ php -f searchNearest.php
    8.  length     : 150000
    9.  key        : 38737
    10.  key search : 0.189424991608
    11.  array sort : 0.31040596962
    12.  
    13. $ php -f searchNearest.php
    14.  length     : 150000
    15.  key        : 148977
    16.  key search : 0.233227014542
    17.  array sort : 0.339351892471
    18.  
    19. $ php -f searchNearest.php
    20.  length     : 150000
    21.  key        : 42178
    22.  key search : 0.215394973755
    23.  array sort : 0.318609952927
    24.  
    25. $ php -f searchNearest.php
    26.  length     : 150000
    27.  key        : 136615
    28.  key search : 0.19428396225
    29.  array sort : 0.314887046814
     
  13. kostyl

    kostyl Guest

    TheShock
    я знал, что ты не выдержишь ;), честно, молодец.
     
  14. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.254
    Симпатии:
    0
    Адрес:
    Київ
    спасибо. я становлюсь предсказуемым :)))
     
  15. kostyl

    kostyl Guest

    TheShock
    относительно меня ты становишься менее линивым. Я тоже раньше не мог удержаться, а сейчас лень.