Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: разбиение массива на пары и тройки

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
jonston
Отправлено: 20 Сентября, 2013 - 05:34:41
Post Id



Посетитель


Покинул форум
Сообщений всего: 455
Дата рег-ции: Март 2011  


Помог: 3 раз(а)




Здравствуйте!Есть такой массив допустим
PHP:
скопировать код в буфер обмена
  1. array(asus, hp, dell, sony, samsumg, lenovo)
.Нужно разбить его на три массива $triplets, $pairs, $units.$units уже есть.Это сам массив.На пары я разбил так:
PHP:
скопировать код в буфер обмена
  1.  
  2.         foreach($filters as $filter_key => $filter_val){
  3.             foreach($filters as $key => $val){
  4.                 if($key > $filter_key)
  5.                     $pairs[] = array($filter_val, $val);
  6.             }
  7.         }
  8.  

А вот как разбить на тройки?
(Добавление)
jonston пишет:
Здравствуйте!Есть такой массив допустим
PHP:
скопировать код в буфер обмена
  1. array(asus, hp, dell, sony, samsumg, lenovo)
.Нужно разбить его на три массива $triplets, $pairs, $units.$units уже есть.Это сам массив.На пары я разбил так:
PHP:
скопировать код в буфер обмена
  1.  
  2.         foreach($filters as $filter_key => $filter_val){
  3.             foreach($filters as $key => $val){
  4.                 if($key > $filter_key)
  5.                     $pairs[] = array($filter_val, $val);
  6.             }
  7.         }
  8.  

А вот как разбить на тройки?

Справился сам.
PHP:
скопировать код в буфер обмена
  1.  
  2.         foreach($filters as $filter_key => $filter_val){
  3.             $l1 = array();
  4.             foreach($filters as $key => $val){
  5.                 if($key > $filter_key){
  6.                     foreach($filters as $k => $v){
  7.                         if($k > $key)
  8.                             $triplets[] = array($filter_val, $val, $v);
  9.                     }                    
  10.                 }
  11.             }
  12.         }
  13.  

Любопытно посмотреть на профессиональный подход.Чует мое сердце, что это можно сделать проще.Или правильнее.


-----
$i = 0;
$i = $i++ + ++$i; ?
 
 Top
EuGen Администратор
Отправлено: 20 Сентября, 2013 - 09:13:40
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




PHP:
скопировать код в буфер обмена
  1. $rgData     = ['asus', 'hp', 'dell', 'sony', 'samsumg', 'lenovo'];
  2. $rgPairs    = array_chunk($rgData, 2);
  3. $rgTriplets = array_chunk($rgData, 3);
  4. //var_dump($rgPairs, $rgTriples);

?


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
jonston
Отправлено: 20 Сентября, 2013 - 15:51:45
Post Id



Посетитель


Покинул форум
Сообщений всего: 455
Дата рег-ции: Март 2011  


Помог: 3 раз(а)




EuGen пишет:
PHP:
скопировать код в буфер обмена
  1. $rgData     = ['asus', 'hp', 'dell', 'sony', 'samsumg', 'lenovo'];
  2. $rgPairs    = array_chunk($rgData, 2);
  3. $rgTriplets = array_chunk($rgData, 3);
  4. //var_dump($rgPairs, $rgTriples);

?

Великолепнейший язык.Спасибо!


-----
$i = 0;
$i = $i++ + ++$i; ?
 
 Top
jonston
Отправлено: 22 Сентября, 2013 - 13:24:32
Post Id



Посетитель


Покинул форум
Сообщений всего: 455
Дата рег-ции: Март 2011  


Помог: 3 раз(а)




EuGen пишет:
PHP:
скопировать код в буфер обмена
  1. $rgData     = ['asus', 'hp', 'dell', 'sony', 'samsumg', 'lenovo'];
  2. $rgPairs    = array_chunk($rgData, 2);
  3. $rgTriplets = array_chunk($rgData, 3);
  4. //var_dump($rgPairs, $rgTriples);

?

Попробовал.Немного не то.Нужно что бы на выходе получились все возможные комбинации пар.


-----
$i = 0;
$i = $i++ + ++$i; ?
 
 Top
EuGen Администратор
Отправлено: 22 Сентября, 2013 - 15:28:14
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Все возможные комбинации пар - не то же самое, что "разбить на пары". Соответственно, равны ли пары <x,y> и <y,x> ? Нужны ли пары <x,x>? Те же вопросы по тройкам.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
jonston
Отправлено: 23 Сентября, 2013 - 12:45:08
Post Id



Посетитель


Покинул форум
Сообщений всего: 455
Дата рег-ции: Март 2011  


Помог: 3 раз(а)




EuGen пишет:
Все возможные комбинации пар - не то же самое, что "разбить на пары". Соответственно, равны ли пары <x,y> и <y,x> ? Нужны ли пары <x,x>? Те же вопросы по тройкам.

Нет все уникальные комбинации из [x,y,z] => [x,y], [x,z], [y,z].Реверс не учитываем.Мой вариант вполне рабочий.Может просто есть вариант более оптимизированный?

(Отредактировано автором: 23 Сентября, 2013 - 12:46:55)



-----
$i = 0;
$i = $i++ + ++$i; ?
 
 Top
EuGen Администратор
Отправлено: 23 Сентября, 2013 - 13:37:14
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Могу предложить лишь более общий вариант, который будет работать независимо от того, нужны ли пары или тройки или четвёрки (и т.п.):
PHP:
скопировать код в буфер обмена
  1. function decartProductPair($rgArg0, $rgArg1, $bUnique=false)
  2. {
  3.    $rgResult=[];
  4.    for($i=0; $i<count($rgArg0); $i++)
  5.    {
  6.       for($j=0; $j<count($rgArg1); $j++)
  7.       {
  8.          if($bUnique)
  9.          {
  10.             if($i!=$j)
  11.             {
  12.                $rgResult[$i*$i+$j*$j]=array_merge((array)$rgArg0[$i], (array)$rgArg1[$j]);
  13.             }
  14.          }
  15.          else
  16.          {
  17.             $rgResult[]=array_merge((array)$rgArg0[$i], (array)$rgArg1[$j]);
  18.          }
  19.       }
  20.    }
  21.    return array_values($rgResult);
  22. }
  23. function decartProduct()
  24. {
  25.    $rgArgs   = func_get_args();
  26.    $bUnique  = false;
  27.    if(isset($rgArgs[0]) && is_bool($rgArgs[0]))
  28.    {
  29.       $bUnique = array_shift($rgArgs);
  30.    }
  31.    if(!count($rgArgs))
  32.    {
  33.       return [];
  34.    }
  35.    $rgResult = array_shift($rgArgs);
  36.    while($rgArg=array_shift($rgArgs))
  37.    {
  38.       $rgResult=decartProductPair($rgResult, $rgArg, $bUnique);
  39.    }
  40.    return $rgResult;
  41. }

- выглядит, разумеется, не проще. Чтобы получить пары:
PHP:
скопировать код в буфер обмена
  1. $rgResult = decartProduct(true, $rgData, $rgData);

- тройки:
PHP:
скопировать код в буфер обмена
  1. $rgResult = decartProduct(true, $rgData, $rgData, $rgData);

- но у троек есть неоднозначность. С математической точки зрения тройка <x, y, y> - корректна. Но допускаются ли повторения внутри тройки по условиям Вашей задачи - неясно.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
jonston
Отправлено: 23 Сентября, 2013 - 14:16:37
Post Id



Посетитель


Покинул форум
Сообщений всего: 455
Дата рег-ции: Март 2011  


Помог: 3 раз(а)




EuGen пишет:
Но допускаются ли повторения внутри тройки по условиям Вашей задачи - неясно.

Нет, не допускается.Порядок расположения элементов не важен.Если массив [a, b, c, d, e] то на выходе получаем [a, b, c], [a, b, d], [a, b, e], [b, c, d], [d, c, e], [c, d, e].То есть компания из трех переменных встречается каждый раз по разному, но нет разницы в каком порядке.


-----
$i = 0;
$i = $i++ + ++$i; ?
 
 Top
EuGen Администратор
Отправлено: 23 Сентября, 2013 - 14:22:38
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




jonston
Из Вашего последнего примера неясно, какими должны быть тройки. Похоже, речь не только о том, чтобы значение не повторялось в тройке, но ещё и некоторое ограничение на весь набор троек - потому что если добавить условие запрета повторения значения только внутри тройки:
PHP:
скопировать код в буфер обмена
  1. function decartProductPair($rgArg0, $rgArg1, $bUnique=false)
  2. {
  3.    $rgResult=[];
  4.    for($i=0; $i<count($rgArg0); $i++)
  5.    {
  6.       for($j=0; $j<count($rgArg1); $j++)
  7.       {
  8.          if($bUnique)
  9.          {
  10.             if($i!=$j && !count(array_intersect((array)$rgArg0[$i], (array)$rgArg1[$j])))
  11.             {
  12.                $rgResult[$i*$i+$j*$j]=array_merge((array)$rgArg0[$i], (array)$rgArg1[$j]);
  13.             }
  14.          }
  15.          else
  16.          {
  17.             $rgResult[]=array_merge((array)$rgArg0[$i], (array)$rgArg1[$j]);
  18.          }
  19.       }
  20.    }
  21.    return array_values($rgResult);
  22. }

- всё равно получается 45 значений для
PHP:
скопировать код в буфер обмена
  1. $rgData = ['asus', 'hp', 'dell', 'sony', 'samsumg', 'lenovo'];

- вполне уникальных для каждой тройки, но, похоже, не тех, что нужны Вам.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
jonston
Отправлено: 23 Сентября, 2013 - 14:40:04
Post Id



Посетитель


Покинул форум
Сообщений всего: 455
Дата рег-ции: Март 2011  


Помог: 3 раз(а)




Юджин, вот рабочий вариант для троек.
PHP:
скопировать код в буфер обмена
  1.  
  2.         foreach($filters as $filter_key => $filter_val){
  3.             $l1 = array();
  4.             foreach($filters as $key => $val){
  5.                 if($key > $filter_key){
  6.                     foreach($filters as $k => $v){
  7.                         if($k > $key)
  8.                             $triplets[] = array($filter_val, $val, $v);
  9.                     }                    
  10.                 }
  11.             }
  12.         }
  13.  

Вообще у меня немного другая задача.Там вообще сложняк.Отпишусь в следующей теме.


-----
$i = 0;
$i = $i++ + ++$i; ?
 
 Top
EuGen Администратор
Отправлено: 23 Сентября, 2013 - 14:43:03
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Суть не в "рабочем варианте" а в понимании того, что нужно получить (из примера мне это было не очевидно)


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
jonston
Отправлено: 23 Сентября, 2013 - 14:59:23
Post Id



Посетитель


Покинул форум
Сообщений всего: 455
Дата рег-ции: Март 2011  


Помог: 3 раз(а)




EuGen пишет:
Суть не в "рабочем варианте" а в понимании того, что нужно получить (из примера мне это было не очевидно)

Что конкретно непонятно?


-----
$i = 0;
$i = $i++ + ++$i; ?
 
 Top
EuGen Администратор
Отправлено: 23 Сентября, 2013 - 16:16:54
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




jonston пишет:
Если массив [a, b, c, d, e] то на выходе получаем [a, b, c], [a, b, d], [a, b, e], [b, c, d], [d, c, e], [c, d, e]

Вот это и непонятно. Декартово произведение Вам не подходит. Единственно возможный вариант иной комбинации - это сочетание. Их количество вычисляется как

- и потому для Вашего случая должно быть равно 10.

Задача нахождения сочетаний - достаточно интересна. Я написал вариант, как сделать это для любого числа искомых комбинаций:
PHP:
скопировать код в буфер обмена
  1.  
  2. function nextAssoc($sAssoc)
  3. {
  4.    if(false !== ($iPos = strrpos($sAssoc, '01')))
  5.    {
  6.       $sAssoc[$iPos]   = '1';
  7.       $sAssoc[$iPos+1] = '0';
  8.       return substr($sAssoc, 0, $iPos+2).
  9.              str_repeat('0', substr_count(substr($sAssoc, $iPos+2), '0')).
  10.              str_repeat('1', substr_count(substr($sAssoc, $iPos+2), '1'));
  11.    }
  12.    return false;
  13. }
  14.  
  15. function getAssoc(array $rgData, $iCount=2)
  16. {
  17.    if(count($rgData)<$iCount)
  18.    {
  19.       return null;
  20.    }
  21.    $sAssoc   = str_repeat('0', count($rgData)-$iCount).str_repeat('1', $iCount);
  22.    $rgResult = [];
  23.    do
  24.    {
  25.       $rgResult[]=array_intersect_key($rgData, array_filter(str_split($sAssoc)));
  26.    }
  27.    while($sAssoc=nextAssoc($sAssoc));
  28.    return $rgResult;
  29. }

- например,
PHP:
скопировать код в буфер обмена
  1. print_r(getAssoc(['a', 'b', 'c', 'd', 'e'], 3));

даст на выходе:
Спойлер (Отобразить)


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB