问题描述:
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
这个就是约瑟夫环问题的实际场景,有一种是要通过输入n,m,k三个正整数,来求出列的序列。
下面我们来分析下列代码的实现思想:
1、利用php递归
2、用于存放处列序列的数组$storage和剩余元素组成的新数组$temp作为递归数组的$arr
3、$start 作为指定元素开始位置的数组的下标(指针),可以作为出列元素的判断元素之一。
/**
* $arr 数组
* $k 指定开始的位置
* $m 数到m的那个人出列(或者整数倍的m)
**/
function doJosephus($arr,$k,$m)
{
//静态变量(存在数据不能计时清除的危险)
static $storage = array();
$temp = array();
$cnt = count($arr);
//判断数组是否有元素,否则退出执行
if ($cnt) {
$k_mod = ($cnt-$k+1)%$m-$m;//为下一次调用时设置的开始位置
static $start = 1;//初始化开始位置为1
for ($i=0;$i<$cnt;$i++){
if ($i>=$k-1) {//从大于等于$k位置(计为1),开始处理
if (!($start%$m)) {
//等于$m长度则入库
$storage[] = array_shift($arr);
}else{
//不属于$m长度的则计入下一个处理的数组
$temp[] = array_shift($arr);
}
//指针在一个环内不断的往前走(加1)
$start++;
}else{
//在$k位置之前的元素全部进入下一次循环
$temp[] = array_shift($arr);
}
}
//递归调用开始(模拟链接环的作用)
doJosephus($temp,$k_mod,$m);
}
return $storage;
}
此文章仅供学习参考之用。