检查整数是否在任何范围内的更快方法?

时间:2010-11-30 12:32:51

标签: php

我想知道是否还有另一种缩短方法?以下是我正在寻找做同样事情的例子。

if($c <= 100){
    echo 'A';
}elseif($c <= 200 && $c > 100){
    echo 'B';
}elseif($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';
}

5 个答案:

答案 0 :(得分:2)

更快更短 - 没有*,但你可以使它更灵活和优雅

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));

(*假设范围是任意的。如果我们更多地了解范围,例如,它们被排序,或者总是相交,或者遵循一些公式,我们可以找到更好的算法)。

答案 1 :(得分:0)

不是内置的,但因为你的计划并不复杂

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;
}

另一种适用于任意限制的解决方案。我假设,有一个上限

$c; // value to test
$ranges = array(101,201,199); // and so on
$index = 0;
while ($ranges[$index] >= $c) { $index++; }
// Do something useful with "$index"

答案 2 :(得分:0)

我猜你可以编写一个辅助函数来完成一个充满匿名函数的数组。如果你要执行的代码很简单,那么它会很好用。否则,如果您使用的是PHP5.3,则可以使用适当的lambdas来执行更复杂的操作。这会使它更整洁。

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;"),
    // ...
));

答案 3 :(得分:0)

如果分支数量很大,您可能需要查看binary search tree 这将减少需要针对任何特定分支进行测试的最大比较次数(尽管最小测试次数也会增加)。

e.g。以下情况至少有2个测试,最多3个测试。在上面的示例中,最多有4个测试。

if ($c< 202)
{
  if($c < 101){ 
    // action 101 here 
  }
  else { 
    // action 202 here 
  }
}
else {
  if($c < 303){ 
    // action here 
  }
  elseif($c < 404){ 
   // action here 
}

编辑:取决于'缩短'的含义。按照你的头衔“更快”假设表现。

编辑(你已经更新了List):Point'A'中的案例只需要一次比较测试,而'AA'掉落将失败~25次测试。假设所有箱中的数据均匀分布,平均测试次数将为~12('L'),而在二叉树形成中,大多数检查将是Log2(N)+ 1 - 即6个测试将覆盖32个分支。不幸的是,在你的情况下,偶数'100'的数据存在差距。如果你排除这些(即如果值MOD 100 == 0然后落到'AA'),那么你可以对其余的排列进行单侧测试。

答案 4 :(得分:0)

这真的是你的代码吗?如果$ c是100的倍数,你总是想要返回AA吗?

以最少的代码获得相同结果的最快方法是....

$res=array('A','B','C',....);
if (($c % 100) && ($c>0) && ($c<2100)) {
   echo $res[(integer)($c/100)];
} else {
   echo 'AA';
}

但我会使用像sterofrog那样的解决方案。