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 Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
Алтенрион
Отправлено: 28 Октября, 2013 - 10:08:47
Post Id



Частый гость


Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012  
Откуда: Москва, Россия


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




Задача :
Пользователь вводит n записей в базу. После запроса формируется многомерный массив типа :
PHP:
скопировать код в буфер обмена
  1.  
  2. 0=>
  3.         [0=>[
  4.                 0=>'1',
  5.                 1=>'one1' ],
  6.         1=>[
  7.                 0=>'1',
  8.                 1=>'two1' ],
  9.         2=>[
  10.                 0=>'1',
  11.                 1=>'three1' ]
  12.         ],
  13. 1=>
  14.         [0=>[
  15.                 0=>'2',
  16.                 1=>'one2' ],
  17.         1=>[
  18.                 0=>'2',
  19.                 1=>'two2' ],
  20.         2=>[
  21.                 0=>'2',
  22.                 1=>'three2' ]
  23.         ],
  24. ...
  25. )
  26.  
  27.  


Первый уровень массивов - это группы( 0,1,...) , в каждой группе записаны пользователи ( 0,1,2).
У каждого пользователя два свойства: 0-это ключ группы, 1- это его имя.

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


Получить одномерный массив не трудно :

PHP:
скопировать код в буфер обмена
  1.  
  2. for ($i = 0; $i < count($array); $i++) {
  3.             for ($j = 0; $j < count($array[$i]); $j++) {
  4.                 $arry [] = $array[$i][$j];
  5.             }
  6.         }
  7.  
  8.  


Но как отсортировать пользователей, скажем что бы они шли в списке :


PHP:
скопировать код в буфер обмена
  1.  
  2.         0=>[
  3.                 0=>'1',
  4.                 1=>'one1' ],
  5.         1=>[
  6.                 0=>'2',
  7.                 1=>'one2' ],
  8.         2=>[
  9.                 0=>'1',
  10.                 1=>'two1' ],
  11.         3=>[
  12.                 0=>'2',
  13.                 1=>'two2' ]
  14.        
  15. ......
  16. ]
  17.  


Подскажите ! Уже перебробовал и делать array_chunk($array,2) и сравнивать индексы в паре и переносить в другой массив, но не понял как сделать прерывание цикла, И пробовал просто пробегать по первым элементам массивов , и делать unset, или array_shift первым элементам после переноса их в новый массив-список, но не получается...
 
 Top
IllusionMH
Отправлено: 28 Октября, 2013 - 11:14:43
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


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




Алтенрион, добавляйте по одному элементу из каждого массива в одной итрерации цикла.
 
 Top
Алтенрион
Отправлено: 28 Октября, 2013 - 11:19:41
Post Id



Частый гость


Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012  
Откуда: Москва, Россия


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




В каждом массиве групп, может быть разное количество пользователей, можете привести пример ?

Я пришел к выводу что необходимо переносить первого пользователя группы в новый массив, и удалять его из родительского, и переиндексировать массив родитель, но не получается реализовать все в 1 цикл...
 
 Top
IllusionMH
Отправлено: 28 Октября, 2013 - 11:21:35
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


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




Алтенрион, а что мешает наращивать индекс и проверять есть ли такой элемент массива в первом или во втором случае?
Если там есть разница хотя бы в 2 элемента, по в любом случае 2 элемента из одного массива будут идти подряд.
 
 Top
Алтенрион
Отправлено: 28 Октября, 2013 - 11:41:32
Post Id



Частый гость


Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012  
Откуда: Москва, Россия


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




я допускаю что я ошибаюсь в подходе сортировки.
главная цель - из общего списка пользователей, сгруппировать пары из пользователй разных групп случайным образом.
пользователей будет примерно поровну, может быть нечетное кл-во(т.е. 1 может остаться без пары (последний) ).
рандомизацию делал сортируя пользоватей внутри групп методом shuffle() .
дошел до прямого перебора так как не смог реализовать дейсвительно случайную парную группмровку.
можете подсказаль алгоритм ?
 
 Top
IllusionMH
Отправлено: 28 Октября, 2013 - 12:09:33
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


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




Алтенрион, примерно так.

PHP:
скопировать код в буфер обмена
  1. $m = array(array('a1','a2','a3','a4'),array('b1','b2','b3','b4','b5',));
  2.  
  3. shuffle($m[1]);
  4. $groups = array();
  5. $i = 0;
  6. do {
  7.   if($e1 = isset($m[0][$i])){
  8.     $groups[$i][] = $m[0][$i];
  9.   }
  10.   if($e2 = isset($m[1][$i])){
  11.     $groups[$i][] = $m[1][$i];
  12.   }
  13.   $i++;
  14. } while($e1||$e2);
  15. var_dump($m, $groups);

$m - изначальный массив
$groups - массив групп
 
 Top
Алтенрион
Отправлено: 28 Октября, 2013 - 12:51:51
Post Id



Частый гость


Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012  
Откуда: Москва, Россия


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




групп может быть больше 2... , как можно учесть динамическое получение колва групп в данном переборе?
наверн метод count($m)
 
 Top
IllusionMH
Отправлено: 28 Октября, 2013 - 13:22:55
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


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




Алтенрион, ну тут уже более сложная логика, в случае если группы будут по 6, 4, 4 участников, а нужно делать именно пары из разных групп, то тогда нужно переделывать всю логику, для учета необходимости создания пар из 2 и 3 групп.
 
 Top
Алтенрион
Отправлено: 28 Октября, 2013 - 13:32:37
Post Id



Частый гость


Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012  
Откуда: Москва, Россия


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




в том и проблема( если бы группы было точно 2, можно было бы просто сделать два массива и поочереди совместить их элементы.
сложность как раз в необходимости работы с несколькими группами. есть вероятность что групп будет блльше чем их участников. скажем около 7 групп, по 3 участника в каждой
 
 Top
IllusionMH
Отправлено: 28 Октября, 2013 - 13:55:37
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


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




Алтенрион, есть алгоритм, но не совсем случайный. Проверил на нескольких простых случаях.
1) Делаем шафл всех массивов
2) Потом делаем шафл порядка этих массивов(чуть больше рандома, можно попробовать делать его после каждого выбора пары, но может не давать результатов)
3) Ищется 2 самых длинных массива
4) Формируется пара из двух последних элементов(pop быстрее shift)
5) Повторяем с пункта 3 (если иммется множество массивов одинаковой длины, то убывать они будут примерно одинаково, так что тут можно попробовать сделать шафл порядка массивов.)

(Отредактировано автором: 28 Октября, 2013 - 13:56:42)

 
 Top
Алтенрион
Отправлено: 28 Октября, 2013 - 14:07:32
Post Id



Частый гость


Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012  
Откуда: Москва, Россия


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




как раз из-за специфичной сложности, я и перешел от полного рандома, к последовательному вычленению первых элементов каждой группы, перераспределению ключей внутри групп, и повтору итерации. но не понимаю как работать с массивом в котором я делал array_shift, после первой итерации. либо он берет исходный, либо я ухожу в безконечный цикл...(
(Добавление)
Повторюсь, вполне допускаю возможность работы не с массивом групп пользователей, а с массивом пользователей у которых есть индекс группы :

PHP:
скопировать код в буфер обмена
  1.  
  2.  0 =>
  3.       0 => '1'
  4.       1 => 'Артем'
  5.   1 =>
  6.       0 => '1'
  7.       1 => 'Игорь'
  8.   2 =>
  9.       0 => '1'
  10.       1 => 'Максим Спесивцев'
  11.   3 =>
  12.       0 => '2'
  13.       1 => 'Антон'
  14.   4 =>
  15.       0 => '2'
  16.       1 => 'Графчиков'
  17.   5 =>
  18.       0 => '3'
  19.       1 => 'Абра кадабра'
  20.  
  21.  


Не знаю как это может облегчить задачу перебора массива и выведение алгоритма. Я пробовал такой массив разбивать через array_chunk($array, 2) и затем проверять равенство индексов групп, и если не равны, то делать

где $list - массив в который собирал нормальные пары, а $array[0]- элемент с парой после разделения по 2,

но не получилось создать адекватный цикл для проверки, не хватило знаний по работе с массивами видимо. Не понимаю видимо полностью как работают unset и array_shift...

Может работая с таким общим массивом попроще будет?

(Отредактировано автором: 28 Октября, 2013 - 14:08:56)

 
 Top
IllusionMH
Отправлено: 28 Октября, 2013 - 15:07:30
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


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




Алтенрион, вот примерная реализация алгоритма изложенного мной выше. Вроде работает но нужно больше тестов. Если найдете ошибки - пишите.
http://codepad[dot]viper-7[dot]com/084CDF
 
 Top
Алтенрион
Отправлено: 29 Октября, 2013 - 00:33:19
Post Id



Частый гость


Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012  
Откуда: Москва, Россия


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




Протестирую утром, отпишу результаты.
 
 Top
Алтенрион
Отправлено: 29 Октября, 2013 - 13:16:03
Post Id



Частый гость


Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012  
Откуда: Москва, Россия


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




Блпагодарю! Огромное спасибо за реализацию алгоритма!)) Вы сделали ощутимый вклад в автоматизацию отечественного детского спорта)

(Отредактировано автором: 29 Октября, 2013 - 13:16:24)

 
 Top
IllusionMH
Отправлено: 29 Октября, 2013 - 14:34:33
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


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




Алтенрион, тут обсудил вопрос с товарищем Кобитом.
Есть другой алгоритм.
0) Шафл всех массивов
1) Берем самый длинный массив. "первый"
2) Поочередно из всех других массивов тянем по одному элементу, пока не составим все пары для "первого" массива.
3) Возвращаемся к п. 1

работа с индексами и дополнительными проверками сложнее, зато можно избежать сортировки.
Дает более "равномерное" распределение пар из разных групп (в случае 4х одинаковых по длине групп не будет вечных пар 1 2, 3 4 (если не выполнять шафл порядка массивов на каждом шагу)). Возможно в предельных случаях могут быть косяки, но пока не придумал такой.
 
 Top
Страниц (2): [1] 2 »
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Напишите за меня, пожалуйста »


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



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

 
Powered by ExBB FM 1.0 RC1. InvisionExBB