php实现约瑟夫环经典问题

问题描述:

        约瑟夫环是一个数学的应用问题:已知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;
     }


此文章仅供学习参考之用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值