约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。
/***
* @param $m 每次读数
* @param $n 总monkey数
*/
function yuesefu($m,$n)
{
//初始化 monkey数组
for ($i = 1; $i <= $n; $i++) {
$yuesefu[] = $i;
}
//print_r($yuesefu);
$j = 0;//第x次报数
while (true) {
$j++;
$num = count($yuesefu);
if ($num == 1) {//数组中只剩下一个元素后,结束循环
echo "last monkey:" . array_pop($yuesefu) . "\n";
break;
}
$p = $m % $num;
$p = $p == 0 ? $num : $p;//每次出列monkey的编号,一定是 $m % $n的结果,结果为零表示最后一位出列
echo "$j,out:" . $yuesefu[$p - 1] . "\n";
unset($yuesefu[$p - 1]);//提出列
$yuesefu = array_values($yuesefu);//重新处理数组的key
}
}
yuesefu(4,5);
运行结果
1,out:4
2,out:5
3,out:1
4,out:3
last monkey:2