Мне нужно равномерно выбрать n элементов из массива. Я думаю, что лучший способ объяснить это на примере.
скажи, что у меня есть:
массив [0,1,2,3,4] и мне нужно выбрать 3 числа .. 0,2,4.
Конечно, если длина массива <= <em>n , мне просто нужно вернуть весь массив.
Я почти уверен, что для этого существует определенный алгоритм, я пытался найти, и я взглянул на Введение в алгоритмы , но не смог найти ничего, что соответствовало бы моим потребностям (вероятно, упустил из виду)
Проблема, с которой я столкнулся, заключается в том, что я не могу придумать способ масштабирования этого до любого массива [p..q], выбирая N равномерно элементов.
примечание: я не могу просто выбрать четные элементы из примера выше ..
Пара других примеров;
массив [0,1,2,3,4,5,6], 3 элемента; Мне нужно получить 0,3,6
массив [0,1,2,3,4,5], 3 элемента; Мне нужно получить 0, 2 или 3 и 5
EDIT:
больше примеров:
массив [0,1,2], 2 элемента: 0,2
массив [0,1,2,3,4,5,6,7], 5 элементов: 0,2, либо 3, либо 4, 5,7
и да, я бы хотел всегда включать первый и последний элементы.
РЕДАКТИРОВАТЬ 2:
то, о чем я думал, было что-то вроде ... сначала + последний элемент, а затем продолжил свой путь, используя медианное значение. Хотя я застрял / смутился, пытаясь это сделать.
Я посмотрю на алгоритм, который вы публикуете. спасибо!
РЕДАКТИРОВАТЬ 3:
Вот улучшенная версия решения incrediman с PHP. Работает также с ассоциативными массивами, сохраняя ключи.
<?php
/**
* Selects $x elements (evenly distributed across $set) from $set
*
* @param $set array : array set to select from
* @param $x int : number of elements to select. positive integer
*
* @return array|bool : selected set, bool false on failure
*/
///FIXME when $x = 1 .. return median .. right now throws a warning, division by zero
function select ($set, $x) {
//check params
if (!is_array($set) || !is_int($x) || $x < 1)
return false;
$n = count($set);
if ($n <= $x)
return $set;
$selected = array ();
$step = ($n - 1) / ($x - 1);
$keys = array_keys ($set);
$values = array_values($set);
for ($i=0; $i<$x; $i++) {
$selected[$keys[round($step*$i)]] = $values[round($step*$i)];
}
return $selected;
}
?>
Возможно, вы можете реализовать Итератор , но мне не нужно заходить так далеко.