2019年2月25日17:29:17php
Josephus有過的故事:39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓。因而決定了自殺方式,41我的排成一個圓圈,由第1我的開始報數,每報數到第3人該人就必須自殺。而後下一個從新報數,直到全部人都自殺身亡爲止。然而Josephus 和他的朋友並不想聽從,Josephus要他的朋友先僞裝聽從,他將朋友與本身安排在第16個與第31個位置,因而逃過了這場死亡遊戲。
this
抽象出的問題是 N我的圍成一圈,從第S我的開始報數,報到C的人出圈,從出去的人的下一位,繼續從下一任開始從新報數,報到m的人出圈;如此往復,直到全部人出圈。spa
final class Kid { public $no; public $next = null; public function __construct($no) { $this->no = $no; } }
<?php /* * 環形鏈表 解決約瑟夫問題 */ final class CircularLinkedList { public function addKid($n = 0, &$head = null) { for ($i = 0; $i < $n; $i++) { $Kid = new Kid($i + 1); if ($i == 0) { //第一個小孩的狀況 $head = $Kid; //對象賦值,是引用賦值 $head->next = $Kid; //本身指向本身 $current = $head; //對象賦值,是引用賦值 } else { $current->next = $Kid; $Kid->next = $head; // //繼續指向下一個 $current = $current->next; } } } /* * $start 從幾開始 * $count 數到幾就出圈 */ public function play(Kid $head, $start, $count) { $current = $head; //移動指針從$start 移動到 while (1) { if ($current->no == $start) { break; } $current = $current->next; } // p($current); // pp($this->countKids($current)); // $all = $this->countKids($current); while ($current->next != $current->next->next) { //少移動一位,方便一處節點 for ($i = 1; $i < $count; $i++) { $current = $current->next; } //去除節點 // p($current); p('出去的小孩是 --' . $current->next->no); $current->next = $current->next->next; // p($current); //移動指針,移到刪除節點的下一位就是從新數數的那個節點 $current = $current->next; } p($current->no); } public function countKids(Kid $head) { $current = $head; $count = 1; while ($head->no != $current->next->no) { $count++; $current = $current->next; } return $count; } }
調用指針
$CircularLinkedList = new CircularLinkedList(); $CircularLinkedList->addKid(10, $head); $CircularLinkedList->play($head, 3, 2);
結果code
出去的小孩是 --5 出去的小孩是 --8 出去的小孩是 --1 出去的小孩是 --4 出去的小孩是 --9 出去的小孩是 --3 出去的小孩是 --10 出去的小孩是 --7 出去的小孩是 --2 6