Hi,
I need to evenly select n elements from an array. I guess the best way to explain is by example.
say I have:
array [0,1,2,3,4] and I need to select 3 numbers.. 0,2,4.
of course, if the array length <= n, I just need to return the whole array.
I'm pretty sure there's a defined algorithm for this, been trying to search, and I took a look at Introduction to algorithms but couldn't find anything that met my needs (probably overlooked it)
The problem I'm having is that I can't figure out a way to scale this up to any array [ p..q ], selecting N evenly elements.
note: I can't just select the even elements from the example above..
A couple other examples;
array[0,1,2,3,4,5,6], 3 elements ; I need to get 0,3,6
array[0,1,2,3,4,5], 3 elements ; I need to get 0, either 2 or 3, and 5
EDIT:
more examples:
array [0,1,2], 2 elems : 0,2
array [0,1,2,3,4,5,6,7], 5 elems : 0,2, either 3 or 4, 5,7
and yes, I'd like to include first and last elements always.
EDIT 2:
what I was thinking was something like .. first + last element, then work my way up using the median value. Though I got stuck/confused when trying to do so.
I'll take a look at the algo you're posting. thanks!
EDIT 3:
Here's a souped up version of incrediman solution with PHP. Works with associative arrays as well, while retaining the keys.
<?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;
}
?>
You can probably implement an Iterator but I don't need to take it that far.