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 :: Помогите перетасовать динамический массив.
Первый уровень массивов - это группы( 0,1,...) , в каждой группе записаны пользователи ( 0,1,2).
У каждого пользователя два свойства: 0-это ключ группы, 1- это его имя.
Необходимо перебрать массив так, чтобы они выстроились без повторения двух индексов групп подряд, в 1 список(одномерный массив).
Подскажите ! Уже перебробовал и делать array_chunk($array,2) и сравнивать индексы в паре и переносить в другой массив, но не понял как сделать прерывание цикла, И пробовал просто пробегать по первым элементам массивов , и делать unset, или array_shift первым элементам после переноса их в новый массив-список, но не получается...
IllusionMH
Отправлено: 28 Октября, 2013 - 11:14:43
Активный участник
Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011 Откуда: .kh.ua
Помог: 242 раз(а)
Алтенрион, добавляйте по одному элементу из каждого массива в одной итрерации цикла.
Алтенрион
Отправлено: 28 Октября, 2013 - 11:19:41
Частый гость
Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012 Откуда: Москва, Россия
Помог: 0 раз(а)
В каждом массиве групп, может быть разное количество пользователей, можете привести пример ?
Я пришел к выводу что необходимо переносить первого пользователя группы в новый массив, и удалять его из родительского, и переиндексировать массив родитель, но не получается реализовать все в 1 цикл...
IllusionMH
Отправлено: 28 Октября, 2013 - 11:21:35
Активный участник
Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011 Откуда: .kh.ua
Помог: 242 раз(а)
Алтенрион, а что мешает наращивать индекс и проверять есть ли такой элемент массива в первом или во втором случае?
Если там есть разница хотя бы в 2 элемента, по в любом случае 2 элемента из одного массива будут идти подряд.
Алтенрион
Отправлено: 28 Октября, 2013 - 11:41:32
Частый гость
Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012 Откуда: Москва, Россия
Помог: 0 раз(а)
я допускаю что я ошибаюсь в подходе сортировки.
главная цель - из общего списка пользователей, сгруппировать пары из пользователй разных групп случайным образом.
пользователей будет примерно поровну, может быть нечетное кл-во(т.е. 1 может остаться без пары (последний) ).
рандомизацию делал сортируя пользоватей внутри групп методом shuffle() .
дошел до прямого перебора так как не смог реализовать дейсвительно случайную парную группмровку.
можете подсказаль алгоритм ?
IllusionMH
Отправлено: 28 Октября, 2013 - 12:09:33
Активный участник
Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011 Откуда: .kh.ua
Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012 Откуда: Москва, Россия
Помог: 0 раз(а)
групп может быть больше 2... , как можно учесть динамическое получение колва групп в данном переборе?
наверн метод count($m)
IllusionMH
Отправлено: 28 Октября, 2013 - 13:22:55
Активный участник
Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011 Откуда: .kh.ua
Помог: 242 раз(а)
Алтенрион, ну тут уже более сложная логика, в случае если группы будут по 6, 4, 4 участников, а нужно делать именно пары из разных групп, то тогда нужно переделывать всю логику, для учета необходимости создания пар из 2 и 3 групп.
Алтенрион
Отправлено: 28 Октября, 2013 - 13:32:37
Частый гость
Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012 Откуда: Москва, Россия
Помог: 0 раз(а)
в том и проблема( если бы группы было точно 2, можно было бы просто сделать два массива и поочереди совместить их элементы.
сложность как раз в необходимости работы с несколькими группами. есть вероятность что групп будет блльше чем их участников. скажем около 7 групп, по 3 участника в каждой
IllusionMH
Отправлено: 28 Октября, 2013 - 13:55:37
Активный участник
Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011 Откуда: .kh.ua
Помог: 242 раз(а)
Алтенрион, есть алгоритм, но не совсем случайный. Проверил на нескольких простых случаях.
1) Делаем шафл всех массивов
2) Потом делаем шафл порядка этих массивов(чуть больше рандома, можно попробовать делать его после каждого выбора пары, но может не давать результатов)
3) Ищется 2 самых длинных массива
4) Формируется пара из двух последних элементов(pop быстрее shift)
5) Повторяем с пункта 3 (если иммется множество массивов одинаковой длины, то убывать они будут примерно одинаково, так что тут можно попробовать сделать шафл порядка массивов.)
Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012 Откуда: Москва, Россия
Помог: 0 раз(а)
как раз из-за специфичной сложности, я и перешел от полного рандома, к последовательному вычленению первых элементов каждой группы, перераспределению ключей внутри групп, и повтору итерации. но не понимаю как работать с массивом в котором я делал array_shift, после первой итерации. либо он берет исходный, либо я ухожу в безконечный цикл...( (Добавление)
Повторюсь, вполне допускаю возможность работы не с массивом групп пользователей, а с массивом пользователей у которых есть индекс группы :
Не знаю как это может облегчить задачу перебора массива и выведение алгоритма. Я пробовал такой массив разбивать через array_chunk($array, 2) и затем проверять равенство индексов групп, и если не равны, то делать
где $list - массив в который собирал нормальные пары, а $array[0]- элемент с парой после разделения по 2,
но не получилось создать адекватный цикл для проверки, не хватило знаний по работе с массивами видимо. Не понимаю видимо полностью как работают unset и array_shift...
Может работая с таким общим массивом попроще будет?
Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011 Откуда: .kh.ua
Помог: 242 раз(а)
Алтенрион, вот примерная реализация алгоритма изложенного мной выше. Вроде работает но нужно больше тестов. Если найдете ошибки - пишите. http://codepad[dot]viper-7[dot]com/084CDF
Алтенрион
Отправлено: 29 Октября, 2013 - 00:33:19
Частый гость
Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012 Откуда: Москва, Россия
Помог: 0 раз(а)
Протестирую утром, отпишу результаты.
Алтенрион
Отправлено: 29 Октября, 2013 - 13:16:03
Частый гость
Покинул форум
Сообщений всего: 180
Дата рег-ции: Сент. 2012 Откуда: Москва, Россия
Помог: 0 раз(а)
Блпагодарю! Огромное спасибо за реализацию алгоритма!)) Вы сделали ощутимый вклад в автоматизацию отечественного детского спорта)
Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011 Откуда: .kh.ua
Помог: 242 раз(а)
Алтенрион, тут обсудил вопрос с товарищем Кобитом.
Есть другой алгоритм.
0) Шафл всех массивов
1) Берем самый длинный массив. "первый"
2) Поочередно из всех других массивов тянем по одному элементу, пока не составим все пары для "первого" массива.
3) Возвращаемся к п. 1
работа с индексами и дополнительными проверками сложнее, зато можно избежать сортировки.
Дает более "равномерное" распределение пар из разных групп (в случае 4х одинаковых по длине групп не будет вечных пар 1 2, 3 4 (если не выполнять шафл порядка массивов на каждом шагу)). Возможно в предельных случаях могут быть косяки, но пока не придумал такой.
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.