За последние 24 часа нас посетил 18951 программист и 1608 роботов. Сейчас ищет 891 программист ...

Помогите решить алгоритм

Тема в разделе "PHP для новичков", создана пользователем sey, 3 авг 2008.

  1. sey

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

    С нами с:
    28 янв 2008
    Сообщения:
    32
    Симпатии:
    0
    есть массив users, ключ содержит id, а значение ip адрес юзеров. надо создать другой массив из id юзеров, которые ip адреса повторяются. т.е.

    $users = array(
    1 => '127.0.0.1',
    2 => '127.0.0.2',
    3 => '127.0.0.1',
    4 => '127.0.0.3',
    5 => '127.0.0.3',
    6 => '127.0.0.4');

    $mustdieusers = array(1, 3, 4, 5);

    заранее спасибо.
     
  2. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    м?
    PHP:
    1. <?
    2. $users = array(
    3. 1 => '127.0.0.1',
    4. 2 => '127.0.0.2',
    5. 3 => '127.0.0.1',
    6. 4 => '127.0.0.3',
    7. 5 => '127.0.0.3',
    8. 6 => '127.0.0.4');
    9. $mustdieusers=array();
    10. foreach($users as $key=>$val) {
    11.     foreach($users as $k=>$v) {
    12.         if (md5($v)==md5($val) && $key!==$k && !in_array($key,$mustdieusers)) {
    13.             $mustdieusers[]=$key;
    14.             break;
    15.         }
    16.     }
    17. }
    18.  
    19. ?>
     
  3. NOmeR1

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

    С нами с:
    11 май 2008
    Сообщения:
    97
    Симпатии:
    0
    Так попроще)
    Код (Text):
    1. <?php
    2. $users = array(1 => '127.0.0.1', 2 => '127.0.0.2', 3 => '127.0.0.1', 4 => '127.0.0.3', 5 => '127.0.0.3', 6 => '127.0.0.4');
    3. $bad_users = array();
    4. foreach($users as $k => $user) {
    5.     $tmp_arr = $users;
    6.     unset($tmp_arr[$k]);
    7.     if(in_array($user, $tmp_arr)) {
    8.         $bad_users[] = $k;
    9.     }
    10. }
    11. var_export($bad_users);
    12. ?>
     
  4. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    не, не проще - быстрее...
     
  5. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Может что-то типа
    PHP:
    1. <?php
    2. $clear_u = array_unique($users); //Вернет 1, 2, 4, 6
    3. $copys = array_diff_assoc($users, $clear_u); //Вернет 3, 5
    4. while (list($key, $value) = each($copys)) {
    5.     $index = array_search($value, $clear_u ); //Вернет 1 и 4
    6.     $copys[$index] = $clear_u[$index];
    7. }
    8. sort($copys);
    9. ?>
    Пока писал, уже два варианта накатали :)
     
  6. sey

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

    С нами с:
    28 янв 2008
    Сообщения:
    32
    Симпатии:
    0
    всем спасибо
     
  7. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Еще один вариант
    PHP:
    1.  
    2. <?php
    3. $values = array_count_values($users); //Получаем 127.0.0.1 => 2,  127.0.0.2 => 1, 127.0.0.3 => 2, 127.0.0.4 => 1
    4. foreach ($values as $key => $value) {
    5.     if ($value > 1) {
    6.         $tmp_array = array_keys($users, $key); //Получаем Array (1,3), Array (4,5)
    7.         for ($i = 0; $i < sizeof($tmp_array); $i++) {
    8.            
    9.             $multiusers[$tmp_array[$i]] = $users[$tmp_array[$i]];
    10.         }
    11.     }
    12. }
    13. ?>
    14.  
    Программирование - интересная штука)
     
  8. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    sey, ты какой вариант взял =))
     
  9. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Mr.M.I.T.
    У тебя 2 foreach + 2 md5, твой в пролете :p
     
  10. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    PHP:
    1. <?php
    2. $users = array(
    3.     1 => '127.0.0.1',
    4.     2 => '127.0.0.2',
    5.     3 => '127.0.0.1',
    6.     4 => '127.0.0.3',
    7.     5 => '127.0.0.3',
    8.     6 => '127.0.0.4'
    9. );
    10. $mustdieusers = array();
    11.  
    12. foreach ($users as $id => $ip) {
    13.     if (count(array_keys($users, $ip)) > 1) {
    14.         $mustdieusers[] = $id;
    15.     }
    16. }
    17.  
    18. print_r($mustdieusers);
     
  11. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    зато самый простой в понимании...
    блин, у Sergey89 самый нормальный получился...
     
  12. NOmeR1

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

    С нами с:
    11 май 2008
    Сообщения:
    97
    Симпатии:
    0
    У меня работает не хуже, т.к. столько же функций, такой же цикл, но мой вариант первее написан :p
     
  13. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Sergey89
    Черт. Когда свои варианты писал, то в голове так и крутилось "нифига не оптимально".
     
  14. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
  15. NOmeR1

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

    С нами с:
    11 май 2008
    Сообщения:
    97
    Симпатии:
    0
    Время исполнения скриптов (доли секунды):

    Код (Text):
    1. Mr.M.I.T.   =   9.3936920166E-5
    2. NOmeR1      =   4.19616699219E-5
    3. Sergey89     =  4.41074371338E-5
    4. nimistar    =   6.103515625E-5
    Победитель - NOmeR1 :p

    P.S. Скрипт крекера выдавал ошибку :(
     
  16. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    NOmeR1
    простой вынос функции фильтрации
    PHP:
    1. # <?
    2.  
    3. function c($v){
    4.     return $v>1;
    5. }
    6.  
    7.  
    8.   $users = array(
    9.   1 => '127.0.0.1',
    10.   2 => '127.0.0.2',
    11.   3 => '127.0.0.1',
    12.   4 => '127.0.0.3',
    13.   5 => '127.0.0.3',
    14.   6 => '127.0.0.4');
    15.  
    16.  
    17. $mustdieusers = array_keys(array_intersect($users,array_keys(array_filter(array_count_values($users),'c'))));
    и
    Код (Text):
    1. 3.4093856811523
     
  17. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    PHP:
    1. <?php
    2. $mustdieusers = array();
    3.  
    4. foreach (array_count_values($users) as $ip => $count) {
    5.     if ($count > 1) {
    6.         $mustdieusers = array_merge($mustdieusers, array_keys($users, $ip));
    7.     }
    8. }
    9.  
    Всё сильно зависит от условий. Этот метод будет очень быстрым, когда много уникальных IP адресов или наоборот много повторяющихся.

    p.s. можете провести тест на большом массиве прогнав каждый метод в цикле 100 раз.
     
  18. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    Sergey89 неполенился проверил - ну не ста записях, но на 30 записях в масиве юзерс!
    (интераций 1000)

    Код (Text):
    1. А = min: 0.00011897; max: 0.00179291; average: 0.00013030
    2. Б = min: 0.00005507; max: 0.00031090; average: 0.00005847
    и на 6 записях
    Код (Text):
    1. А = min: 0.00001383; max: 0.00019503; average: 0.00001647
    2. Б = min: 0.00001502; max: 0.00014997; average: 0.00001648
    где А - твой код
    а Б - мой ...

    а вообщем шляпа ... если рассмотреть в деталях ... то там распределение затрат идет следующим образом - первый раз всегда долго - потом быстро (иногда вкрапления долго, очень)

    П.С.: я это к тому что стоит пытаться исполнять код на встроенных процедурах, у них запас мощности несравнимо выше!
     
  19. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Странно, но но у меня другие цифры :)

    Код (Text):
    1. // 6
    2. A: 0.00784
    3. B: 0.00889
    4.  
    5. // 1000
    6. A: 0.04183
    7. B: 0.13853
     
  20. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    =)))
    жестокая тема
    ЗЫ. Следующий вариант алгоритма предлогаю оформить согласно стандартам MVC =)))
     
  21. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    NOmeR1
    У меня оба работали вчера. Надо сегодня потестить :) PHP какой у тебя?
     
  22. NOmeR1

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

    С нами с:
    11 май 2008
    Сообщения:
    97
    Симпатии:
    0
    Всё заработало, это я протупил. Забыл массив $users запихнуть. :D
     
  23. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Еще один вариант
    PHP:
    1. <?php
    2. $tmp_array = Array();
    3. while (list($key, $value) = each($users)) {
    4.     $id = array_search($value, $tmp_array);
    5.     if ($id !== false) {
    6.         $multiusers[$id] = $value;
    7.         $multiusers[$key] = $value;
    8.     }
    9.     $tmp_array[$key] = $value;
    10. }
    11. sort($multiusers);
    12. ?>