您的位置:首页 > 其它

循环与递归

2010-04-03 16:54 176 查看
// 提出问题:
/**
* 一个射击运动员打靶,靶共有 10 环,运动员连续开 10 抢打中 90 环的可能性有多少种?
*/
//
// 循环实现
$sum = 0;
for( $i = 0; $i < 11; $i++)
for( $j = 0; $j < 11; $j++)
for( $k = 0; $k < 11; $k++)
for( $l = 0; $l < 11; $l++)
for( $m = 0; $m < 11; $m++)
for( $n = 0; $n < 11; $n++)
for( $o = 0; $o < 11; $o++)
for( $p = 0; $p < 11; $p++)
for( $q = 0; $q < 11; $q++)
for( $r = 0; $r < 11; $r++)
if( 90 == $i + $j + $k + $l + $m + $n + $o + $p + $q + $r)
$sum++;
echo $sum;
// 分析
// 1, 时间复杂度很高,我在我电脑上根本就没有运行出来
// 2, 要找出所有 10 枪 90 环的情况,循环实现 需要测试 10 的 10 次方
// 3, 程序没有前瞻性;如果运动员前 2 抢打了不到 10 环,就没必要打(循环下去)了,因为后面 8 枪不可能超过 80 环
//
// 递归实现
class M{
private static $sum = 0;
private function __construct(){}
//
/**
* $left_score: 还需要打多少环
* $left_num: 还能打多少枪
* $scores: 满足 10 枪 90 环的情况
*/
public static function compute( $left_score, $left_num, $scores = array() ){
if( $left_score < 0 || ( $left_num + 1) * 10 < $left_score){ // 不满足条件,提前退出
return;
}
if( $left_num == 0){ // 满足 10 枪 90 个
$scores[ $left_num] = $left_score;
self::output( $scores);
return;
}
for( $i = 0; $i < 11; $i++){
$scores[ $left_num] = $i;
self::compute( $left_score - $i, $left_num - 1, $scores);
}
}
//
public static function output( $scores = array() ){
// print_r( $scores);
self::$sum++;
}
//
public static function getSum(){
return self::$sum;
}
}
//
$d = time();
M::compute( 90, 9, array());
echo( M::getSum() ); // 92378
echo '<br />';
echo time() - $d;  // 大概需要 3, 4 秒
// 说明:
// 1, $left_num(枪数)是: 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
//
// 关于这个循环与递归的转变
// 1, 递归过程是在 M::compute() 中进行的,$left_num 控制的是 循环实现 中的 10 个嵌套循环
//
//
// 需要说明的:
$i = 1;
$j = 2;
func( $i++, ++$j ); // 这种调用情况传递给形参的是 ( 1, 3),就是说在调用函数的时候 自增自减 操作还是以原来的方式运行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: