За последние 24 часа нас посетили 52668 программистов и 1765 роботов. Сейчас ищут 823 программиста ...

Перебор массива

Тема в разделе "PHP для новичков", создана пользователем EndoCrinolog, 29 янв 2014.

  1. EndoCrinolog

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

    С нами с:
    4 фев 2012
    Сообщения:
    205
    Симпатии:
    1
    Адрес:
    Тольятти
    По-моему, всё описано...
     
  2. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Сдается мне, с сарказмом было сие написано автором поста. Не принимай прямо.
     
  3. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    его вариант несовсем корректен. некоторые значения при переборе он невыводит, например 'aaa'. это так на вскидку.
    чтото сложные у вас решения какието. много букв )))
    Код (PHP):
    1. $dict = 'abx1'; // словарь символов для перебора
    2. define('DICTLEN', strlen($dict) ); // длина словаря
    3. $cur = 'aa';    // значение с которого надо начать
    4. $end = 'aaaa';  // значение на которым закончить перебор
    5. // поехали!
    6. while($cur!=$end) {
    7.     for($i=strlen($cur)-1; $i>=0; --$i) {
    8.         $pos = strpos($dict, $cur[$i]);
    9.         if ($pos==DICTLEN-1) { // no next
    10.             if ($i==0) { // limit left
    11.                 $cur = $dict[0].str_repeat($dict[0],strlen($cur));
    12.             } else { // not limit left
    13.                 $pos2 = strpos($dict, $cur[$i-1]);
    14.                 if ($pos2==DICTLEN-1) continue;
    15.                 $cur[$i-1] = $dict[$pos2+1];
    16.                 $cur = substr_replace($cur, str_repeat($dict[0],strlen($cur)-$i),$i);
    17.             }
    18.         } else $cur[$i] = $dict[$pos+1]; // exist
    19.         break;
    20.     } // for
    21.     echo $cur.'<br>'; // если нужен массив то: str_split($cur);
    22. } // while 
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    ой, баг :D
    вместо
    Код (PHP):
    1.       if (!isset($pointers[$index + 1])) {
    2.         $pointers[$index + 1] = 0;
    3.       }
    4.       $pointers[$index + 1]++; 
    надо
    Код (PHP):
    1.       if (!isset($pointers[$index + 1])) {
    2.         $pointers[$index + 1] = 0;
    3.       } else {
    4.         $pointers[$index + 1]++;
    5.       } 
    поправил
    Код (PHP):
    1. <?php
    2. $chars = ['a', 'b', 'x', '1'];
    3. $word = '1a';
    4. if (empty($word)) {
    5.   $pointers = [0];
    6. } else {
    7.   $we = str_split($word);
    8.   $we = array_reverse($we);
    9.   //$pointers[0] - правый символ
    10.   foreach ($we as $w) {
    11.     foreach ($chars as $ck => $cv) {
    12.       if ($w === $cv) {
    13.         $pointers[] = $ck;
    14.       }
    15.     }
    16.   }
    17. }
    18. $cmax = count($chars) - 1;
    19. for ($i = 0; $i < 10; $i++) {
    20.   $pointers = iter($pointers, $cmax);
    21.   echo buildWord($pointers, $chars), '<br>';
    22. }
    23.  
    24. function buildWord($pointers, $chars) {
    25.   $word = '';
    26.   $pointers = array_reverse($pointers);
    27.   foreach ($pointers as $p) {
    28.     $word .= $chars[$p];
    29.   }
    30.   return $word;
    31. }
    32.  
    33. function iter($pointers, $cmax) {
    34.   $pointers[0]++;
    35.   var_dump($pointers);
    36.   reset($pointers);
    37.   $flag = true;
    38.   $index = 0;
    39.   do {
    40.     if ($pointers[$index] <= $cmax) {
    41.       $flag = false;
    42.     } else {
    43.       $pointers[$index] = 0;
    44.       if (!isset($pointers[$index + 1])) {
    45.         $pointers[$index + 1] = 0;
    46.       } else {
    47.         $pointers[$index + 1]++;
    48.       }
    49.     }
    50.     $index++;
    51.   } while ($flag == true);
    52.   return $pointers;
    53. } 
     
  5. EndoCrinolog

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

    С нами с:
    4 фев 2012
    Сообщения:
    205
    Симпатии:
    1
    Адрес:
    Тольятти
    Не знаю, что там за ошибки, но код работает, подбирает :)
     
  6. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    igordata,
    это
    Код (PHP):
    1. foreach ($we as $w) {
    2.  foreach ($chars as $ck => $cv) {
    3.    if ($w === $cv) {
    4.     $pointers[] = $ck;
    5.   }
    6.  }
    7. }
    можно заменить на
    Код (PHP):
    1. foreach ($we as $w) {
    2.  $pointers[] = array_search($w,$chars); 
    3. }
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    лучше используй исправленную версию. ошибка существенная, чувак.
     
  8. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    провел рефакторинг, оптимайзинг и ускоринг)
    Код (PHP):
    1. $dict = 'abx1'; // словарь символов для перебора
    2. $dict_ = array_flip(str_split($dict)); // вспомогательный массив
    3. define('DICTLEN', strlen($dict)-1 ); // длина словаря
    4. $cur = '1a';    // значение с которого надо начать
    5. $end = 'aaaaa';  // значение на которым закончить перебор
    6. while($cur!=$end) {
    7.     for($i=strlen($cur)-1; $i>=0; --$i) {
    8.         if ($dict_[$cur[$i]]<DICTLEN) {
    9.             $cur[$i] = $dict[$dict_[$cur[$i]]+1]; 
    10.         } else {
    11.             $cur[$i] = $dict[0]; 
    12.             if ($i>0) continue;
    13.             $cur = $dict[0].$cur;
    14.         }
    15.         break;
    16.     } // for
    17.     echo $cur.'<br>'; // если нужен массив то: str_split($cur);
    18. } // while     
     
  9. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    А зачем объявлять константу? Чем переменная была бы плоха?
     
  10. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Вроде не мультибайтная
     
  11. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    тем что переменную можно случайно перезаписать. чтоб подстраховать себя от лишних багов с этим связанных, в процессе кодинга алгоритма.
    а так более ничем.
    да и логичнее так. если она недолжна и не будет меняться никогда на протяжении работы алгоритма - зачем ей быть переменной?)

    Добавлено спустя 1 минуту 7 секунд:
    но выше же ты ее используешь)
    $we = str_split($word);
     
  12. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    хреново. надо заменить.
     
  13. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    кому надо? )
    preg_split() в помощь.
     
  14. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    да, я уже затестил, но отвлёкся на споры о мировоззрении в соседнем топике.

    Код (PHP):
    1. <?php
    2. $chars = ['a', 'b', 'x', '1'];
    3. $word = '1a';
    4. if (empty($word)) {
    5.   $pointers = [0];
    6. } else {
    7.   $we = preg_split('//u', $word, -1, PREG_SPLIT_NO_EMPTY);
    8.   $we = array_reverse($we);
    9.   //$pointers[0] - правый символ
    10.   foreach ($we as $w) {
    11.     foreach ($chars as $ck => $cv) {
    12.       if ($w === $cv) {
    13.         $pointers[] = $ck;
    14.       }
    15.     }
    16.   }
    17. }
    18. $cmax = count($chars) - 1;
    19. for ($i = 0; $i < 10; $i++) {
    20.   $pointers = iter($pointers, $cmax);
    21.   echo buildWord($pointers, $chars), '<br>';
    22. }
    23.  
    24. function buildWord($pointers, $chars) {
    25.   $word = '';
    26.   $pointers = array_reverse($pointers);
    27.   foreach ($pointers as $p) {
    28.     $word .= $chars[$p];
    29.   }
    30.   return $word;
    31. }
    32.  
    33. function iter($pointers, $cmax) {
    34.   $pointers[0]++;
    35.   reset($pointers);
    36.   $flag = true;
    37.   $index = 0;
    38.   do {
    39.     if ($pointers[$index] <= $cmax) {
    40.       $flag = false;
    41.     } else {
    42.       $pointers[$index] = 0;
    43.       if (!isset($pointers[$index + 1])) {
    44.         $pointers[$index + 1] = 0;
    45.       } else {
    46.         $pointers[$index + 1]++;
    47.       }
    48.     }
    49.     $index++;
    50.   } while ($flag == true);
    51.   return $pointers;
    52. } 
     
  15. EndoCrinolog

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

    С нами с:
    4 фев 2012
    Сообщения:
    205
    Симпатии:
    1
    Адрес:
    Тольятти
    Так какой самый конечный код со всеми исправлениями и оптимизациями?:)
     
  16. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    самый последний
     
  17. unrecovered

    unrecovered Новичок

    С нами с:
    24 янв 2014
    Сообщения:
    45
    Симпатии:
    0
    Даже проги на компилируемых языках не могут нормально подобрать пароль больше восьми символов, что уж говорить про интерпретируемый PHP. У меня, например, была халтурка по подбору пароля к zip-файлу. Проц выдавал что-то около 30млн паролей в секунду. Благо я нашел программу, способную задействовать CUDA и чудовищную вычислительную мощь моей видюхи(GTX470, та ещё грелка), скорость подбора возрасла до 700млн. Полный перебор 8ми знаков(цифры, латинские буквы в верхнем и нижнем регистре) занимал около 4 дней непрерывной работы.

    Так что, думаю, шесть символов - предел для данного подхода :)
     
  18. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    проги тут не при чем
     
  19. EndoCrinolog

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

    С нами с:
    4 фев 2012
    Сообщения:
    205
    Симпатии:
    1
    Адрес:
    Тольятти
    ВСЕМ ОГРОМНОЕ СПАСИБО ^_^
     
  20. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
  21. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    да, подобный вариант тоже пришел мне в голову. ибо сразу была видна аналогия простого увеличения числа в системе по кастомному основанию. с перебором определенных символов. типа как в шестнадцатиричной. но учитывая задачу ТСа, мне пришлось сделать две функции минимум(типа decToMybase() и mybaseToDec()), плюс цикл, плюс определение с какого начать(мы же не с нуля начинаем) и каким закончить...
    в общем моя реализация показалась слишком громоздкой. потому и пришел к другому варианту.
     
  22. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
  23. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    например возмем 16-тиричную систему счисления. принцип тотже, только другой набор симовлов. но у нас отличие в том, что набор и кол-во символов другое, и может вообще меняться. тоесть аналого системы счисления, но с произвольным основанием.
     
  24. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Это особый случай системы счисления — bijective projection. Числа "1", "01" и прочие "001" не равны.
    Там на stackoverflow, автор лучшего ответа дает ссылку на вики.
     
  25. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    я не понимаю алгоритм вообще