За последние 24 часа нас посетили 22578 программистов и 1276 роботов. Сейчас ищут 662 программиста ...

Комбинаторика решает =)

Тема в разделе "Прочее", создана пользователем Elkaz, 28 ноя 2008.

  1. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Появилась тут задачка сделать кой-чего. После долгих размышлений пришлось признать, что я не знаю как это сделать.
    Задача
    Есть массив с N элементами. Нужно вывести всех возможных комбинаций.

    Решение
    Для начала нужно вычислить число возможных комбинаций: count ($Array)! Вычесть факториал числа элементов в массиве.

    А дальше-то как? Куда? Почему-то думается, что решение до убийства простое, но под конец пятничного дня я не могу ничего придумать.

    Плюс еще проблема в том, что после 17! числа переваливают за 2 млрд - предел для int =)

    Пример массива:
    PHP:
    1.  
    2. <?php
    3. $Array = array ('1', '2', '3', 'A', 'a', 'B', 'b', 'C', 'c');
    4. ?>
    5.  
     
  2. +Sten+

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

    С нами с:
    27 авг 2007
    Сообщения:
    978
    Симпатии:
    0
    Пришел в голову только очень суровый вариант:

    PHP:
    1. <pre>
    2. <?php
    3. $Array = array ('1', '2', '3', 'A', 'a', 'B');
    4.  
    5. function fac($n){
    6.     if ($n == 1){
    7.      return $n;
    8.     }
    9.     else{
    10.      return $n * fac($n-1);
    11.     }
    12. }
    13.  
    14. $fac = fac(count($Array)); //Вычисляем факториал
    15.  
    16. $varianty = array(); //Сюда будем записывать все возможные варианты
    17.  
    18. //ну и понеслася перебором:
    19.  
    20. while(count($varianty) != $fac) {
    21.     shuffle($Array);
    22.     if(!in_array($Array, $varianty))
    23.      $varianty[] = $Array;
    24. }
    25.  
    26. print_r($varianty);
    27. ?>
     
  3. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Вариант действительно суровый... =) Как-то я не додумался юзать shuffle =)))))))))))))))
     
  4. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    + тут не берутся все возможные комбинации =)
    нужные еще и:
    1
    12
    123
    123A
    123Aa

    AaB
    BaA

    и т.д :)
     
  5. +Sten+

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

    С нами с:
    27 авг 2007
    Сообщения:
    978
    Симпатии:
    0
    Ууу, тогда сложнее все.

    Есть мысль, но через 5 минут ухожу пиво пить, приду раскрою мысль, если не забуду :)
     
  6. dAllonE

    dAllonE Guest

    // dAllonE хотел объяснить, что для этого нужно просто сделать рекурсивную функцию в который бы просто
    // перебирался массив, откидывался первый элемент и отправлялся бы снова на вход функции. Но начав писать пример // задумался и "честно" пообещал себе что потом разберется.
     
  7. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    a /me задумался а зачем оно может быть надо...
     
  8. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Я тоже спустя 5 минут заступорился и отложил на потом.
    P.S. Близок к истине
     
  9. sylex

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

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
    алгоритм простой, т.к. 2 сочетания тока...
    PHP:
    1.  <?php
    2.  $Array = array ('1', '2', '3', '4', 'A');
    3.  
    4.  
    5.  function GetAllVariants($mas)
    6.  {
    7.     $res = array();
    8.     $count = sizeof($mas);
    9.     for ($i=0;$i<$count;$i++) {
    10.         $j = $i-1;
    11.         while (++$j<$count) {
    12.             $res[] = $mas[$i] . $mas[$j];
    13.         }
    14.     }
    15.     return $res;
    16. }
    17.  
    18. print_r(GetAllVariants($Array));
    19.  ?>
     
  10. sylex

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

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
    ой.... йоп, не так прочитал... всех сочетаний???
     
  11. sylex

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

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
  12. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Кстати, ты мне дал массив array ('a', 'b', 'c', 'd'); и сказал, что там булет 4! комбинаций, но это не так. Их там должно быть 4^4 вроде бы.
     
  13. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Угу, просто задача поменялась =)

    array ('a', 'b', 'c', 'd'):
    a
    aa
    aaa
    aaaa

    b
    bb
    bbb
    bbbb

    c
    cc
    ccc
    cccc

    d
    dd
    ddd
    dddd

    ab
    aab
    aaab

    bb
    abb
    ...
     
  14. блудный сын

    блудный сын Активный пользователь

    С нами с:
    18 июн 2008
    Сообщения:
    632
    Симпатии:
    0
    Условие задачи описано слабо. Из него непонятно что все-таки точно нужно. Решая такие задачи действительно можно " вывести всех" :)
     
  15. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Код (Text):
    1.  
    2. Array
    3. (
    4.     [0] => a
    5.     ...
    6.     [338] => dddc
    7.     [339] => dddd
    8. )
    Вариантов на самом деле 4^1 + 4^2 + 4^3 + 4^4
     
  16. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    блудный сын
    Выебнуться я тоже могу =) А смысл?
    Умные люди поняли задачу, что недопоняли - я пояснил выше, чтобы избежать недомолвок. Не надо в теме моей оффтопить. Задача описана конкретно - вывести все возможные комбинации элементов массива
     
  17. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Kreker
    Ага
     
  18. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    И сортировка не понадобилась:

    PHP:
    1. <?php
    2. $array = Array();
    3. $array[1] = $main_array = array ('a', 'b', 'c', 'd');
    4. $size = sizeof($array[1]);
    5.  
    6. $arr_name = 1;
    7. for ($count = 2; $count <= $size; $count++) {
    8.  
    9.     $this_size = sizeof($array[$arr_name]);
    10.     $arr_name++;
    11.     for ($i = 0; $i < $this_size; $i++) {
    12.         $gg = $array[($arr_name-1)][$i];
    13.         for ($x = 0; $x < $size; $x++) {
    14.             $array[$arr_name][] = $gg . $array[1][$x];
    15.         }
    16.        
    17.     }
    18.     $main_array = array_merge($main_array, $array[$arr_name]);
    19.     if ($arr_name > 2)
    20.         unset($array[($arr_name-1)]);
    21. }
    22. unset($array[$arr_name]);
    23. print_r($main_array);
    24. ?>
    Медлительный, правда. При 4х аргументах выдает 2.2 мс, а при 5 уже 50 мс.

    Пытался получить без доп. массивов, но не получилось.

    P.S.
    Код (Text):
    1.  
    2. [239] => tits
    P.S.S. Если все-таки понадобится сортировка:
    PHP:
    1. <?php
    2. function mysort($a, $b) {
    3.     if (strlen($a) > strlen($b))
    4.         return 1;
    5.     else if (strlen($a) < strlen($b))
    6.         return -1;
    7.     else
    8.         return ($a > $b) ? 1 : -1;
    9.    
    10. }
    11. usort($main_array, "mysort");
    12. ?>
    P.S.F.
    Блин, 6 букв и скрипт работат около 10 секунд :(
    Код (Text):
    1.  
    2. [36786] => сиськи
     
  19. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Вот реально сейчас не хватает кнопки спасибо =) И символического пожертвования в виде 1$... Имхо!
     
  20. блудный сын

    блудный сын Активный пользователь

    С нами с:
    18 июн 2008
    Сообщения:
    632
    Симпатии:
    0
    А по формулам комбинаторики число этих вариантов можно высчитать за доли секунды...
     
  21. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Сейчас особо времени нет, но когда будет, прочту и напишу скрипт.
    Но мне кажется, что доли секунды не будет работать. Это все-таки РНР.
     
  22. блудный сын

    блудный сын Активный пользователь

    С нами с:
    18 июн 2008
    Сообщения:
    632
    Симпатии:
    0
    Kreker, ну почему же? Факториал 6 компу посчитать не проблема 1*2*3*4*5*6, а вот перебрать эти варианты - это гораздо дольше...
     
  23. sylex

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

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
    конечно, есть разница, вычислить по формуле число вариантов, или перебрать их все :)
     
  24. dAllonE

    dAllonE Guest

    Одно дело по формуле высчитать число вариантов и совсем другое вывести собственно все эти варианты :)

    ИМХО разница примерно такая же как считать сумму части геометрической прогрессии по фор-ле, или же высчитать все элементы и сложить их ;)
     
  25. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Неужели никто больше не хочет придумать свой вариант :(