Xpoint
   [напомнить пароль]

Сложение объектов и равномерное распределение их последовательности

Метки: [без меток]
2009-12-23 16:06:42 [обр] Tarkh[досье]

Добрый день!
Вопрос прост, подскажите как сложить 2 или более массива + равномерно распределить последовательность в получившемся в итоге?

Пример:

$array1=["red","red","red"];
$array2=["green","green","green","green","green","green"];

после сложения должно получиться:

$array_fin=["green","red","green","green","red","green","green","red","green"];

Как-то так.
При этом изначальных массивов, которые будут складываться может быть более 2-х.
Есть ли в PHP уже что-то созданное, для реализации сложения и равномерного распределения?
Если нет, подскажите пожалуйста логику..?

Спасибо заранее!

спустя 2 минуты [обр] Tarkh[досье]
Простите, в примере $array2 содержит не 6 элементов, а 7. Опечатался.
т.е.
$array2=["green","green","green","green","green","green","green"];
спустя 41 минуту [обр] Thirteensmay(17/157)[досье]
По поводу готового не в курсе, а по поводу логики вроде все просто, делите колво элементов длиннейшего массива на колво элементов других массивов, и соответственно располагаете их элементы между элементами длиннейшего массива через полученный результат деления элементов.
спустя 2 часа 57 минут [обр] Tarkh[досье]

Спасибо за ответ)
Я тут мозг собрал в кучу и решил эту задачу таким вот способом... Если кто может - прокомментируйте, имеет право быть?:

<?
$data=array(); // общий будущий массив.

$array1=array("red","red","red");
$array2=array("green","green","green","green","green","green","green");

$finlength=count($array1)+count($array2);

// обрабатываем $array1
$div=$finlength/count($array1);
$i=1;
foreach ($array1 as $element) {
$diff="0.000000".rand(1000000,9999999);
$key = ($div * $i)+$diff; // создаем подобие индекса очередности

$data["$key"]=$element;
$i++;
}

// обрабатываем $array2
$div=$finlength/count($array2);
$i=1;
foreach ($array2 as $element) {
$diff="0.000000".rand(1000000,9999999); // понижаем вероятность дублей в ключах
$key = ($div * $i)+$diff; // создаем подобие индекса очередности

$data["$key"]=$element;
$i++;
}

// Далее сортируем получившийся массив по ключам
ksort($data);

foreach($data as $key=>$elem){
echo $key." - ".$elem."<br>";
}

?>

Ну естественно обработку массивов можно автоматизировать, я говорю о самой логике.

спустя 42 минуты [обр] Thirteensmay(17/157)[досье]
Вместо рандома просто прибавлять глобально инкрементируемое малое значение ? По идее получится проще, надежнее, менее ресурсоемко, и с более гладким распределением.
спустя 2 часа 9 минут [обр] Илья Cтpeльцын aka SelenIT(24/171)[досье]

А как-нибудь вот так нельзя?

$result = array();

$finlength = $finlength=count($array1)+count($array2);

$interval_num = 0;

for ($i = 0; $i < $finlength; $i++) {
   if (round($i/$finlength, 0) >= $interval_num) {
      $result[$i] = array_shift($array2);
      $interval_num++;
   }
   else $result[$i] = array_shift($array1);
}

Т.е. "в уме" делим итоговый массив на интервалы (по кол-ву вставляемых эл-тов из второго массива), идем циклом, как только перейдем границу соседних интервалов — вставляем туда элемент из второго массива, а сами интервалы (от границы до следующей) заполняем элементами первого массива, сколько влезет. Признаюсь, не проверял, но вроде накладок быть не должно...

спустя 1 минуту [обр] Илья Cтpeльцын aka SelenIT(24/171)[досье]
упс, пардон, лишний $finlength прикопипастил...
спустя 59 минут [обр] Thirteensmay(17/157)[досье]
Илья Cтpeльцын aka SelenIT[досье] Хм, на первый взгляд какойто писец, я чтото похоже не осиливаю, пример с тремя массивами и равномерным распределением, поясните пожалуйста
спустя 9 часов [обр] Филипп Ткачев(20/112)[досье]
Внешний цикл перебирает массивы. Т.е. по сути цикл по строкам двумерного массива.
Итоговый массив формируется добавлением элементов в начало и конец из текущего массива.
Решение о добавлении элементов принимается в зависимости от длины текущего массива.
Получается, что итоговый массив растет от середины.
спустя 3 часа 33 минуты [обр] Tarkh[досье]

Илья Cтpeльцын aka SelenIT[досье]

Попробывал ваш пример - нет, не выходит...
при 2-ух массивах
$array1=["red","red","red"];
$array2=["green","green","green","green","green","green","green"];

вот так выходит:

green
red
red
red

green

Thirteensmay[досье]

Я побавил хвостики RAND для того, чтобы если в разных массивах после умножения получаться одинаковые чиса, то прибавляя туда число типа 0.00000056473841 мы получим некую уникальность в каждом варианте, но разница будет настолько ничтожна, что при ksort() на очередность это не повлияет.

спустя 26 минут [обр] Илья Cтpeльцын aka SelenIT(24/171)[досье]

Thirteensmay[досье], да, во второй строчке цикла действительно писец :) и не только в ней :) надо мне все-таки выспаться до конца года... :))

Имелось в виду примерно это:

$result = array();

$array1 = array_fill(0, 3, 'red');
$array2 = array_fill(0, 7, 'green');

$finlength = count($array1)+count($array2);

$interval_len = $finlength/(count($array2));

$interval_num = 0;

for ($i = 0; $i < $finlength; $i++) {
   if ($i >= round($interval_num * $interval_len)) {
      $result[$i] = array_shift($array2);
      $interval_num++;
   }
   else $result[$i] = array_shift($array1);
}

print_r($result);
спустя 2 часа 32 минуты [обр] Tarkh[досье]

Илья Cтpeльцын aka SelenIT[досье]

О, теперь красота)) Тоже работает! Спасибо за более простой вариант.
Но вопрос в следующем - если появится 3-ий массив и т.д.?

Т.е. допустим если так:

$array1 = array_fill(0, 3, 'red');
$array2 = array_fill(0, 7, 'green');
$array3 = array_fill(0, 13, 'green');

В моем варианте нужно просто добавить еще один цикл (или сделать динамический добавление циклов) и всё будет гут.
А в вашем варианте?

спустя 9 часов [обр] Илья Cтpeльцын aka SelenIT(24/171)[досье]
Tarkh[досье], можно повторять всю эту процедуру, "подмешивая" по одному каждый очередной массив к результату предыдущих "перемешиваний", я думаю.
спустя 19 часов [обр] Dennis F. Latypoff aka funky_dennis(4/78)[досье]
А я думаю, PHP тут вообще не причем, тему надо переместить в "Алгоритмы"
Powered by POEM™ Engine Copyright © 2002-2005