Faster way to check if integer is in any of ranges?
I wonder if there is another way to shorten this ? Here is the example im looking for to do same thing just shorter.
if($c <= 100){
echo 'A';
}elseif($c <= 200 && $c > 100){
echo 'B';
}else开发者_开发百科if($c <= 300 && $c > 200){
echo 'C';
}elseif($c <= 400 && $c > 300){
echo 'D';
}elseif($c <= 500 && $c > 400){
echo 'E';
}elseif($c <= 600 && $c > 500){
echo 'F';
}elseif($c <= 700 && $c > 600){
echo 'Z';
}elseif($c <= 800 && $c > 700){
echo 'H';
}elseif($c <= 900 && $c > 800){
echo 'I';
}elseif($c < 1000 && $c > 900){
echo 'K';
}elseif($c <= 1100 && $c > 1000){
echo 'L';
}elseif($c <= 1200 && $c > 1100){
echo 'M';
}elseif($c < 1300 && $c > 1200){
echo 'N';
}elseif($c <= 1400 && $c > 1300){
echo 'O';
}elseif($c <= 1500 && $c > 1400){
echo 'P';
}elseif($c <= 1600 && $c > 1500){
echo 'Q';
}elseif($c <= 1700 && $c > 1600){
echo 'R';
}elseif($c <= 1800 && $c > 1700){
echo 'S';
}elseif($c <= 1900 && $c > 1800){
echo 'T';
}elseif($c <= 2000 && $c > 1900){
echo 'V';
}elseif($c <= 2100 && $c > 2000){
echo 'X';
}else{
echo 'AA';
}
faster and shorter - no*, but you can make it more flexible and elegant
function find_range($n, $ranges) {
foreach($ranges as $key => $range)
if($n >= $range[0] && $n <= $range[1])
return $key;
return false;
}
$ages = array(
'baby' => array(0, 1),
'child' => array(2, 13),
'teen' => array(14, 19),
'adult' => array(20, 59),
'senior' => array(60, 100)
);
var_dump(find_range(20, $ages));
(* assuming ranges are arbitrary. If we know more about ranges, for example, that they are sorted, or always intersect, or follow some formula, we can find a better algorithm).
You could write an auxiliary function that could take an array full of anonymous functions, I guess. It would work well if your code to execute was nice and simple. Otherwise, if you're on PHP5.3 you could use proper lambdas to do more complex things. That would make it neater.
function integer_in_ranges($integer, $array) {
foreach ($array as $range => $function) {
if ($integer < $range) {
$results[] = $function();
}
}
return $results;
}
integer_in_ranges($c, array(
101 => create_function('', "execute_function(); return TRUE;"),
202 => create_function('', "execute_other_function(); return TRUE;"),
// ...
));
Not builtin, but because your plan is not that complex
switch ((int) (($c - 1) / 100)) {
case 0: /* action here */ break;
case 1: /* action here */ break;
case 2: /* action here */ break;
case 3: /* action here */ break;
default: /* action here */ break;
}
Another solution which works with arbitrary limits. I assume, that there is an upper limit
$c; // value to test
$ranges = array(101,201,199); // and so on
$index = 0;
while ($ranges[$index] >= $c) { $index++; }
// Do something useful with "$index"
Is this really your code? You always want to return AA if $c is a multiple of 100?
The fastest way to get the same result with the least amount of code would be....
$res=array('A','B','C',....);
if (($c % 100) && ($c>0) && ($c<2100)) {
echo $res[(integer)($c/100)];
} else {
echo 'AA';
}
But I would use a solution like that from sterofrog.
If the number of branches is large, you might want to look at a binary search tree This will reduce the maximum number of comparisons that any specific branch will need to be tested against (although the minimum number of tests will also increase).
e.g. The below case there is a minimum of 2 tests and a maximum of 3 tests. In your example above, there is a maximum of 4 tests.
if ($c< 202)
{
if($c < 101){
// action 101 here
}
else {
// action 202 here
}
}
else {
if($c < 303){
// action here
}
elseif($c < 404){
// action here
}
Edit : Depends on what you mean by 'shorten'. As per your title 'faster' am assuming performance.
Edit (you've updated the List) : Case in Point 'A' needs only one comparison test, whereas the 'AA' fall through will have failed ~25 tests. Assuming an even distribution of data across all bins, the average number of tests would be ~12 ('L') whereas in a binary tree formation, the most checks would be Log2(N) + 1 - i.e. 6 tests would cover 32 branches. Unfortunately in your case, there are gaps in the data on the even '100's. If you exclude these (i.e. if value MOD 100 == 0 then fall through to 'AA') then you can do just a one sided test for the rest of the permutations.
精彩评论