├── README.md ├── document ├── 2分木.ppt ├── 7パズル.pptx └── ハノイの塔.pptx ├── file └── maze.csv └── src ├── dijkstraTest.php ├── fizzBuzz.php ├── knapsackTest.php ├── mazeTest.php ├── part ├── BinaryTree.php ├── Bucket.php ├── ChainHashBox.php ├── Knapsack.php ├── Maze.php ├── Pattern.php ├── Queen.php ├── RingBuffer.php ├── SevenPuzzle.php └── TreeNode.php ├── recursion ├── eightQueen.php ├── euclidean.php ├── factorial.php ├── fibonacci.php └── hanoi.php ├── ringBufferTest.php ├── search ├── binarySearch.php ├── boyerMooreSearch.php ├── chainHashSearch.php └── linearSearch.php ├── sevenPuzzleTest.php ├── shintyokuhadoudesuka.php ├── sort ├── bubbleSort.php ├── insertionSort.php ├── mergeSort.php ├── quickSort.php ├── selectionSort.php └── shellSort.php └── tree └── binaryTreeTest.php /README.md: -------------------------------------------------------------------------------- 1 | # PHPを用いたアルゴリズムとデータ構造に関してのコードです。 2 | ## 探索 3 | ### [チェインハッシュ法による探索](https://github.com/Khanashima/algorithm/blob/master/src/search/chainHashSearch.php) 4 | ### [バイナリサーチ](https://github.com/Khanashima/algorithm/blob/master/src/search/binarySearch.php) 5 | ### [リニアサーチ](https://github.com/Khanashima/algorithm/blob/master/src/search/linearSearch.php) 6 | ### [深さ探索](https://github.com/Khanashima/algorithm/blob/master/src/mazeTest.php) 7 | ### [文字列探索 Boyer Moore法](https://github.com/Khanashima/algorithm/blob/master/src/search/boyerMooreSearch.php) 8 | ### [2分木](https://github.com/Khanashima/algorithm/blob/master/src/tree/binaryTreeTest.php) 9 | 10 | ## ソート 11 | ### [マージソート](https://github.com/Khanashima/algorithm/blob/master/src/sort/mergeSort.php) 12 | ### [クイックソート](https://github.com/Khanashima/algorithm/blob/master/src/sort/quickSort.php) 13 | ### [シェルソート](https://github.com/Khanashima/algorithm/blob/master/src/sort/shellSort.php) 14 | ### [単純挿入ソート](https://github.com/Khanashima/algorithm/blob/master/src/sort/insertionSort.php) 15 | ### [単純選択ソート](https://github.com/Khanashima/algorithm/blob/master/src/sort/selectionSort.php) 16 | ### [バブルソート](https://github.com/Khanashima/algorithm/blob/master/src/sort/bubbleSort.php) 17 | 18 | ## その他 19 | ### [fizzBuzz](https://github.com/Khanashima/algorithm/blob/master/src/fizzBuzz.php) 20 | ### [リングバッファ](https://github.com/Khanashima/algorithm/blob/master/src/ringBufferTest.php) 21 | ### [階乗の計算](https://github.com/Khanashima/algorithm/blob/master/src/recursion/factorial.php) 22 | ### [ハノイの塔](https://github.com/Khanashima/algorithm/blob/master/src/recursion/hanoi.php) 23 | ### [ユークリッドの互除法](https://github.com/Khanashima/algorithm/blob/master/src/recursion/euclidean.php) 24 | ### [7パズル](https://github.com/Khanashima/algorithm/blob/master/src/sevenPuzzleTest.php) 25 | ### [8個王妃問題](https://github.com/Khanashima/algorithm/blob/master/src/recursion/eightQueen.php) 26 | ### [ダイクストラ法](https://github.com/Khanashima/algorithm/blob/master/src/dijkstraTest.php) 27 | ### [ナップザック問題](https://github.com/Khanashima/algorithm/blob/master/src/knapsackTest.php) 28 | ### [フィボナッチ数列 (メモ化再帰含む)](https://github.com/Khanashima/algorithm/blob/master/src/recursion/fibonacci.php) 29 | -------------------------------------------------------------------------------- /document/2分木.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khanashima/algorithm/bd2db96cb88b3ea18746f52438ff1f5b368415d5/document/2分木.ppt -------------------------------------------------------------------------------- /document/7パズル.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khanashima/algorithm/bd2db96cb88b3ea18746f52438ff1f5b368415d5/document/7パズル.pptx -------------------------------------------------------------------------------- /document/ハノイの塔.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Khanashima/algorithm/bd2db96cb88b3ea18746f52438ff1f5b368415d5/document/ハノイの塔.pptx -------------------------------------------------------------------------------- /file/maze.csv: -------------------------------------------------------------------------------- 1 | 0,0,S,0,X,0 2 | 0,G,X,0,0,0 3 | X,0,0,X,0,0 4 | X,X,0,0,0,X 5 | -------------------------------------------------------------------------------- /src/dijkstraTest.php: -------------------------------------------------------------------------------- 1 | $currentCost[$i]) { 39 | //パターン洗い出しが終わってなく、所要時間の短い駅を調べる 40 | $minTime = $currentCost[$i]; 41 | $minStation = $i; 42 | } 43 | } 44 | } 45 | if ($minTime == -1) { 46 | //全ての駅が確定したか、最初の所要時間が無限大のとき 47 | break; 48 | } 49 | 50 | // 自分の駅から伸びているすべての駅の所要時間を調べる 51 | for ($i = 0; $i < STATION_NUMBER; $i++) { 52 | if (!$fix[$i] && $adjacencyMatrix[$minStation][$i] > 0) { 53 | // 自分の駅経由で移動する場合の必要時間 54 | $newTime = $minTime + $adjacencyMatrix[$minStation][$i]; 55 | if ($currentCost[$i] == -1 || $currentCost[$i] > $newTime) { 56 | // 今登録されている時間よりも、この駅経由で移動した時間が速いので、新しい時間を登録する 57 | $currentCost[$i] = $newTime; 58 | } 59 | } 60 | } 61 | // 自分の駅を確定する 62 | $fix[$minStation] = true; 63 | } 64 | for ($i = 0; $i < STATION_NUMBER; $i++) { 65 | echo ($stations[START_STATION] . "→" . $stations[$i] . ":" . $currentCost[$i] . "分"); 66 | echo '
'; 67 | } -------------------------------------------------------------------------------- /src/fizzBuzz.php: -------------------------------------------------------------------------------- 1 | '; 26 | } -------------------------------------------------------------------------------- /src/knapsackTest.php: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | addProduct(2,2); 15 | $knapsack->addProduct(3,4); 16 | $knapsack->addProduct(5,7); 17 | $knapsack->addProduct(6,10); 18 | $knapsack->addProduct(9,30); 19 | 20 | //ナップザックを解く 21 | $knapsack->solveKnapsack(); 22 | ?> 23 | 24 | -------------------------------------------------------------------------------- /src/mazeTest.php: -------------------------------------------------------------------------------- 1 | search(0, 2)); -------------------------------------------------------------------------------- /src/part/BinaryTree.php: -------------------------------------------------------------------------------- 1 | value = $value; 13 | $node->leftNode = null; 14 | $node->rightNode = null; 15 | return $node; 16 | } 17 | 18 | public static function insertNode($value, $node) { 19 | if ($node->value == $value) { 20 | return false; 21 | } 22 | 23 | if ($node->value > $value) { 24 | //ノードの値より小さい時。左の子のノードに 25 | if ($node->leftNode != null) { 26 | //既に左のノードにデータがある時、次のノードに進む 27 | self::insertNode($value, $node->leftNode); 28 | } else { 29 | //左のノードにデータを挿入 30 | $node->leftNode = self::createNewNode($value); 31 | return true; 32 | } 33 | } else { 34 | //ノードの値より大きい時。右の子のノードに 35 | if ($node->rightNode != null) { 36 | //既に右のノードにデータがある時、次のノードに進む 37 | self::insertNode($value, $node->rightNode); 38 | } else { 39 | //右のノードにデータを挿入 40 | $node->rightNode = self::createNewNode($value); 41 | return true; 42 | } 43 | } 44 | } 45 | 46 | public static function find($value, $node) { 47 | if ($node->value == $value) { 48 | //値が見つかった時 49 | return true; 50 | } 51 | 52 | if ($node->value > $value) { 53 | if (empty($node->leftNode)) { 54 | return false; 55 | } 56 | //探している値が対象のノードより小さい時は左のノードへ 57 | return self::find($value, $node->leftNode); 58 | } else { 59 | if (empty($node->rightNode)) { 60 | return false; 61 | } 62 | //右のノードへ 63 | return self::find($value, $node->rightNode); 64 | } 65 | } 66 | 67 | public static function delete($value, &$tree) { 68 | $rootNode = &$tree; //ルートノードのアドレス 69 | $node = &$tree; //1個ずつ調べ、最後は削除対象のノード 70 | $parent = null; //$nodeの親のノードのアドレス 71 | $direction = 0; //根の場合は0。左の子に進む時は-1を右の時は1 72 | 73 | //削除対象のノードを探索 74 | while ($node !== null && $node->value != $value) { 75 | if ($node->value > $value) { 76 | $parent = &$node; 77 | $node = &$node->leftNode; 78 | $direction = -1; 79 | } else { 80 | $parent = &$node; 81 | $node = &$node->rightNode; 82 | $direction = 1; 83 | } 84 | } 85 | //削除対象が木に無かった時 86 | if ($node == null) { 87 | return false; 88 | } 89 | 90 | //削除対象のノードがある時 91 | if ($node->leftNode == null && $node->rightNode == null) { 92 | //右と左のノードが無い時。つまり、リーフを削除 93 | if ($direction == -1) { 94 | $parent->leftNode = null; 95 | } else { 96 | $parent->rightNode = null; 97 | } 98 | } else if ($node->leftNode == null && $node->rightNode != null) { 99 | //左のノードが無くかつ右のノードがある時 100 | if ($direction == -1) { 101 | $parent->leftNode = $node->rightNode; 102 | } else if ($direction == 1) { 103 | $parent->rightNode = $node->rightNode; 104 | } else if ($direction == 0) { 105 | //木構造で右のノードしかなくルートを削除する時 106 | $rootNode = $node->rightNode; 107 | } 108 | } else if ($node->leftNode != null && $node->rightNode == null) { 109 | //左のノードがあってかつ右のノードが無い時 110 | if ($direction == -1) { 111 | $parent->leftNode = $node->leftNode; 112 | } else if ($direction == 1) { 113 | $parent->rightNode = $node->leftNode; 114 | } else if ($direction == 0) { 115 | //木構造で左のノードしかなくルートを削除する時 116 | $rootNode = $node->leftNode; 117 | } 118 | } else { 119 | //右と左の子がある場合。 120 | //左のノードの最大値と削除したいノードと交換する 121 | $leftBiggest = &$node->leftNode; 122 | $parent = &$node; 123 | $direction = -1; 124 | //右のノードがある限り上書きしていく。 125 | while ($leftBiggest->rightNode != null) { 126 | $parent = &$leftBiggest; 127 | $leftBiggest = &$leftBiggest->rightNode; 128 | $direction = 1; 129 | } 130 | 131 | $node->value = $leftBiggest->value; 132 | if ($direction == -1) { 133 | $parent->leftNode = &$leftBiggest->leftNode; 134 | } else { 135 | $parent->rightNode = &$leftBiggest->leftNode; 136 | } 137 | } 138 | return true; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/part/Bucket.php: -------------------------------------------------------------------------------- 1 | value = $value; 19 | $this->next = $next; 20 | } 21 | 22 | public function getValue() { 23 | return $this->value; 24 | } 25 | 26 | public function getNextAddress() { 27 | return $this->next; 28 | } 29 | } -------------------------------------------------------------------------------- /src/part/ChainHashBox.php: -------------------------------------------------------------------------------- 1 | list = array_fill(0, $size, null); 21 | $this->size = $size; 22 | 23 | } 24 | 25 | public function createHashCode($value) { 26 | $hashCode = $value % $this->size; 27 | return (int)$hashCode; 28 | } 29 | 30 | public function getList() { 31 | return $this->list; 32 | } 33 | 34 | /** 35 | * ハッシュボックスに値を追加する 36 | * @param int $value 値 37 | * 38 | * @return Bool 追加成功の時true 39 | * 追加済みの時false 40 | */ 41 | public function add($value) { 42 | $key = self::createHashCode($value); 43 | $address = null; 44 | if ($this->list[$key]) { 45 | $address = $this->list[$key]; 46 | } 47 | while($address != null) { 48 | if($address->getValue() == $value) { 49 | return false; 50 | } 51 | 52 | if ($address->getValue() == null) { 53 | break; 54 | } 55 | $address = $address->getNextAddress(); 56 | } 57 | $this->list[$key] = new Bucket($value, $this->list[$key]); 58 | return true; 59 | } 60 | 61 | /** 62 | * 値を探す 63 | * @param int $value 探したい値 64 | * 65 | * @return int 探索に成功した時ハッシュボックスのキー 66 | * 失敗した時nullを返す 67 | */ 68 | public function search($value) { 69 | $key = self::createHashCode($value); 70 | $address = null; 71 | if ($this->list[$key]) { 72 | $address = $this->list[$key]; 73 | } 74 | while($address!= null) { 75 | //var_dump($this->list[$key]->getValue()); 76 | //var_dump($value); 77 | //exit(''); 78 | if($address->getValue() == $value) { 79 | return $key; 80 | } 81 | $address = $address->getNextAddress(); 82 | //var_dump($address); 83 | //exit(''); 84 | } 85 | return null; 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /src/part/Knapsack.php: -------------------------------------------------------------------------------- 1 | knapsack = array_fill(0, $capacity + 1, 0); 14 | $this->knapsackCount = $capacity; 15 | $this->product = array(); 16 | } 17 | 18 | public function addProduct($size, $value) { 19 | $this->products[] = array('size' => $size, 'value' => $value); 20 | } 21 | 22 | public function solveKnapsack() { 23 | //ナップザックに詰め込んだ時の値を初期化 24 | $napValue = array_fill(0, $this->knapsackCount + 1, 0); 25 | 26 | //ナップザックの容量を表示する 27 | echo ''; 28 | echo ''; 29 | echo ''; 30 | for ($i = 1; $i < $this->knapsackCount + 1; $i++) { 31 | echo ''; 32 | } 33 | echo ''; 34 | 35 | //扱う商品を1つずつ増やしていく 36 | $productCount = count($this->products); 37 | for ($i = 0; $i < $productCount; $i++) { 38 | //$napIndexの初期値は商品のサイズから。 39 | for ($napIndex = $this->products[$i]['size']; $napIndex < $this->knapsackCount + 1; $napIndex++) { 40 | $newValue = $napValue[$napIndex - $this->products[$i]['size']] + $this->products[$i]['value']; 41 | if ($newValue > $napValue[$napIndex]) { 42 | $napValue[$napIndex] = $newValue; 43 | } 44 | } 45 | //表示 46 | echo ''; 47 | for ($napIndex = 1; $napIndex < $this->knapsackCount + 1; $napIndex++) { 48 | echo ''; 49 | } 50 | echo ''; 51 | } 52 | echo '
ナップサックの大きさ' . $i . '
' . ($i + 1) . '番目の商品まで使用' . $napValue[$napIndex]. '
'; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/part/Maze.php: -------------------------------------------------------------------------------- 1 | maze = self::createMazeFromCSV($filePath); 17 | $this->reached = array(); 18 | $this->isGoal = false; 19 | } 20 | 21 | //迷路のcsvファイルを読み取って、迷路の配列を作成する 22 | public function createMazeFromCSV($filePath) { 23 | $maze = array(); 24 | 25 | $data = file_get_contents($filePath); 26 | $lines = explode("\r\n", $data); 27 | foreach ($lines as $line) { 28 | $maze[] = explode(",",$line); 29 | } 30 | return $maze; 31 | } 32 | 33 | public function search($row, $col) { 34 | //Goalしていたらスキップする。 35 | if ($this->isGoal) { 36 | return true; 37 | } 38 | //迷路の外側か壁の場合は何もしない 39 | if ($row < 0 || self::MAX_H <= $row || $col < 0 || self::MAX_W <= $col || $this->maze[$row][$col] == 'X') { 40 | return false; 41 | } 42 | //既に到達している場合は何もしない 43 | if (isset($this->reached[$row][$col]) && $this->reached[$row][$col] == true) { 44 | return false ; 45 | } 46 | 47 | //今いる地点にチェックしたことを記録する 48 | $this->reached[$row][$col] = true; 49 | 50 | if ($this->maze[$row][$col] == 'G') { 51 | //exit('ゴール'); 52 | $this->isGoal = true; 53 | //echo'
';
54 |             //var_dump($this->reached);
55 |             //echo '
'; 56 | return true; 57 | } 58 | 59 | self::search($row, $col + 1); //右に進む 60 | //var_dump('実行した?'); 61 | self::search($row, $col - 1); //左に進む 62 | //var_dump('実行した?'); 63 | self::search($row + 1, $col); //上に進む 64 | //var_dump('実行した?'); 65 | self::search($row - 1, $col); //下に進む 66 | 67 | //最終結果 68 | if ($this->isGoal) { 69 | return true; 70 | } else { 71 | return false; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/part/Pattern.php: -------------------------------------------------------------------------------- 1 | blockLine = $blockLine; 15 | $this->patternFrom = $patternFrom; 16 | } 17 | } -------------------------------------------------------------------------------- /src/part/Queen.php: -------------------------------------------------------------------------------- 1 | checkRowArray = array_fill(0, 8, false); 16 | $this->checkRightdiagonalArray = array_fill(0, 16, false); 17 | $this->checkLeftdiagonalArray = array_fill(0, 16, false); 18 | $this->count=0; 19 | } 20 | 21 | public function display() { 22 | for ($i = 0; $i < 8; $i++) { 23 | echo $this->answer[$i]; 24 | } 25 | echo '
'; 26 | } 27 | 28 | public function set($row) { 29 | for ($column = 0; $column < 8; $column++) { 30 | if ($this->checkRowArray[$column] == false 31 | && $this->checkRightdiagonalArray[$row + $column] == false 32 | && $this->checkLeftdiagonalArray[$row - $column + 7] == false ) 33 | { 34 | //クィーンをおける時 35 | $this->answer[$row] = $column; 36 | if ($row == 7) { 37 | $this->count++; 38 | self::display(); 39 | } 40 | else { 41 | $this->checkRowArray[$column] = true; 42 | $this->checkRightdiagonalArray[$row + $column] = true; 43 | $this->checkLeftdiagonalArray[$row - $column + 7] = true; 44 | self::set($row + 1); //次の行 45 | 46 | //最後初期化 47 | $this->checkRowArray[$column] = false; 48 | $this->checkRightdiagonalArray[$row + $column] = false; 49 | $this->checkLeftdiagonalArray[$row - $column + 7] = false; 50 | } 51 | } 52 | } 53 | } 54 | 55 | public function getCount() { 56 | return $this->count; 57 | } 58 | } -------------------------------------------------------------------------------- /src/part/RingBuffer.php: -------------------------------------------------------------------------------- 1 | que = array_fill(0, $size, null); 15 | $this->front = 0; 16 | $this->rear = 0; 17 | $this->count = 0; 18 | $this->maxSize = $size; 19 | } 20 | 21 | /** 22 | * リングバッファに値を追加する 23 | * @param int $value 値 24 | * 25 | * @return Bool 追加成功の時true 26 | * 配列が一杯で追加できない時false 27 | */ 28 | public function enque($value) { 29 | if ($this->count == $this->maxSize) { 30 | return false; 31 | } 32 | $this->que[$this->rear++] = $value; 33 | if ($this->rear == $this->maxSize) { 34 | $this->rear = 0; 35 | } 36 | $this->count++; 37 | } 38 | 39 | /** 40 | * リングバッファの値を取得する 41 | * 42 | * @return 値 43 | * 空の時はnullを返す 44 | */ 45 | public function deque() { 46 | if ($this->maxSize == 0) { 47 | return null; 48 | } 49 | $this->count--; 50 | $value = $this->que[$this->front++]; 51 | if ($this->front == $this->maxSize) { 52 | $this->front = 0; 53 | } 54 | return $value; 55 | } 56 | 57 | public function getQue() { 58 | return $this->que; 59 | } 60 | } -------------------------------------------------------------------------------- /src/part/SevenPuzzle.php: -------------------------------------------------------------------------------- 1 | history = array(); 15 | $this->queueBottom = 0; 16 | } 17 | 18 | public function createBlockLine($patternArray) { 19 | return implode(',', $patternArray); 20 | } 21 | 22 | public function revertPattern($blockLine) { 23 | return explode(',', $blockLine); 24 | } 25 | 26 | public function saveHistory($patternArray, $patternFrom) { 27 | $blockLine = self::createBlockLine($patternArray); 28 | //既に登録されていたら何もしない 29 | for ($i=0; $i < count($this->history); $i++) { 30 | if ($this->history[$i]->blockLine == $blockLine) { 31 | return false; 32 | } 33 | } 34 | $this->history[] = new Pattern($blockLine, $patternFrom); 35 | } 36 | 37 | public function solveSevenPuzzle() { 38 | $patternArray = array(); 39 | $blankPos = 0; 40 | 41 | //パターンが空になるまで探索を行う。 42 | while ($this->queueBottom != count($this->history)) { 43 | $blockLine = $this->history[$this->queueBottom]->blockLine; 44 | if ($blockLine == self::ANSWER) { 45 | //history配列のキーを返す。 46 | return $this->queueBottom; 47 | } 48 | $patternArray = self::revertPattern($blockLine); 49 | //移動する前のパターンを控える 50 | $patternArrayOrg = self::revertPattern($blockLine); 51 | 52 | //ボックスに0(空白)がある位置を特定する 53 | for ($blankPos =0; $blankPos < 8; $blankPos++) { 54 | if ($patternArray[$blankPos] == 0) { 55 | break; 56 | } 57 | } 58 | 59 | if ($blankPos > 3) { 60 | //下に空があって上のブロックを下にずらず 61 | $patternArray[$blankPos] = $patternArray[$blankPos-4]; 62 | $patternArray[$blankPos-4] = 0; 63 | self::saveHistory($patternArray, $this->queueBottom); 64 | //配列を移動する前に戻す 65 | $patternArray = $patternArrayOrg; 66 | } 67 | 68 | if ($blankPos < 4) { 69 | //上に空があって下のブロックを上にずらず 70 | $patternArray[$blankPos] = $patternArray[$blankPos + 4]; 71 | $patternArray[$blankPos + 4] = 0; 72 | self::saveHistory($patternArray, $this->queueBottom); 73 | //配列を移動する前に戻す 74 | $patternArray = $patternArrayOrg; 75 | } 76 | 77 | if ($blankPos != 0 && $blankPos != 4) { 78 | //右にずらず。右から持っていくの右端が空の時は何もしない 79 | $patternArray[$blankPos] = $patternArray[$blankPos - 1]; 80 | $patternArray[$blankPos - 1] = 0; 81 | self::saveHistory($patternArray, $this->queueBottom); 82 | //配列を移動する前に戻す 83 | $patternArray = $patternArrayOrg; 84 | } 85 | 86 | if ($blankPos != 3 && $blankPos != 7) { 87 | //左にずらず。左から持っていくの左端が空の時は何もしない 88 | $patternArray[$blankPos] = $patternArray[$blankPos + 1]; 89 | $patternArray[$blankPos + 1] = 0; 90 | self::saveHistory($patternArray, $this->queueBottom); 91 | //配列を移動する前に戻す 92 | $patternArray = $patternArrayOrg; 93 | } 94 | $this->queueBottom++; 95 | } 96 | //見つからなかった 97 | return false; 98 | } 99 | 100 | public function showAnswer($pattern, $endIndex = null) { 101 | if ($endIndex != null) { 102 | $patternNo = $endIndex; 103 | self::showBlock($this->history[$patternNo]->blockLine); 104 | echo '

'; 105 | } 106 | $patternNo = $pattern->patternFrom; 107 | self::showBlock($this->history[$patternNo]->blockLine); 108 | echo '

'; 109 | if ($patternNo == 0) { 110 | //最初にたどり着いたから終了 111 | return true; 112 | } 113 | $pattern = $this->history[$patternNo]; 114 | self::showAnswer($pattern); 115 | } 116 | 117 | public function showBlock($blockLine) { 118 | echo (substr($blockLine, 0, 7)); 119 | echo '
'; 120 | echo (substr($blockLine, 8, 7)); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/part/TreeNode.php: -------------------------------------------------------------------------------- 1 | set(0); 11 | 12 | echo '答えは全部で' . $queen->getCount() . '個です。'; -------------------------------------------------------------------------------- /src/recursion/euclidean.php: -------------------------------------------------------------------------------- 1 | '; 15 | echo '44と13の最大公約数は?'; 16 | var_dump(euclidean(44,13)); 17 | echo '
'; 18 | echo '44と28の最大公約数は?'; 19 | var_dump(euclidean(44,28)); 20 | echo '
'; 21 | echo '44と44の最大公約数は?'; 22 | var_dump(euclidean(44,44)); 23 | echo '
'; 24 | 25 | function euclidean($x, $y) { 26 | if ($y == 0) { 27 | return $x; 28 | } 29 | return euclidean($y, (int)$x % $y); 30 | } -------------------------------------------------------------------------------- /src/recursion/factorial.php: -------------------------------------------------------------------------------- 1 | '; 9 | var_dump(calculateFactorial(4)); 10 | 11 | function calculateFactorial($n) { 12 | if ($n == 1) { 13 | return 1; 14 | } 15 | return $n * calculateFactorial($n - 1); 16 | } -------------------------------------------------------------------------------- /src/recursion/fibonacci.php: -------------------------------------------------------------------------------- 1 | '; 9 | $startTime = microtime(true); 10 | echo 'getFib(35)の答えは' . getFib(35); 11 | $endTime = microtime(true); 12 | $deltaTime = $endTime - $startTime; 13 | echo('
処理にかかった時間は' . $deltaTime . 'ミリ秒です'); 14 | echo '

'; 15 | echo 'メモ化再帰を使った場合のgetFibWithMemo(35)を求める'; 16 | echo '
'; 17 | $startTime = microtime(true); 18 | echo 'getFibWithMemo(35)の答えは' . getFibByMemo(35); 19 | $endTime = microtime(true); 20 | $deltaTime = $endTime - $startTime; 21 | echo('
処理にかかった時間は' . $deltaTime . 'ミリ秒です'); 22 | echo '

'; 23 | echo 'メモ化再帰であれば$n=100もイケちゃう!!
'; 24 | echo 'getFibByMemo(100)の答えは' . getFibByMemo(100); 25 | 26 | function getFib($n) { 27 | if ($n == 0) { 28 | return 1; 29 | } 30 | if ($n ==1) { 31 | return 2; 32 | } 33 | return getFib($n - 1) + getFib($n -2); 34 | } 35 | 36 | $memo = array(); 37 | function getFibByMemo($n) { 38 | global $memo; 39 | if ($n == 0) { 40 | return 1; 41 | } 42 | if ($n ==1) { 43 | return 2; 44 | } 45 | if(isset($memo[$n])) { 46 | return $memo[$n]; 47 | } 48 | return $memo[$n] = getFibByMemo($n - 1) + getFibByMemo($n -2); 49 | } -------------------------------------------------------------------------------- /src/recursion/hanoi.php: -------------------------------------------------------------------------------- 1 | '; 11 | hanoi(3,"A", "B", "C"); 12 | 13 | function hanoi($n, $a, $b, $c) { 14 | if ($n > 0) { 15 | hanoi($n-1, $a, $c, $b); 16 | echo $n .'番目の円盤を' . $a . 'から' .$b. 'に移動する'; 17 | echo '
'; 18 | hanoi($n-1, $c, $b, $a); 19 | } 20 | } -------------------------------------------------------------------------------- /src/ringBufferTest.php: -------------------------------------------------------------------------------- 1 | enque(1); 14 | $que->enque(2); 15 | $que->enque(3); 16 | $que->enque(4); 17 | $que->enque(5); 18 | $que->enque(6); 19 | $que->enque(7); 20 | $que->enque(8); 21 | $que->enque(9); 22 | $que->enque(10); 23 | $que->enque(11); 24 | 25 | echo '
';
26 | var_dump($que->getQue());
27 | echo '
'; 28 | echo $que->deque(); 29 | echo '
'; 30 | echo $que->deque(); 31 | echo '
'; 32 | echo $que->deque(); 33 | echo '
'; 34 | echo $que->deque(); 35 | echo '
'; 36 | echo $que->deque(); 37 | echo '
'; 38 | echo $que->deque(); 39 | echo '
'; 40 | echo $que->deque(); 41 | $que->enque(12); 42 | echo '
'; 43 | echo $que->deque(); 44 | echo '
'; 45 | var_dump($que->getQue()); 46 | echo '
'; 47 | 48 | -------------------------------------------------------------------------------- /src/search/binarySearch.php: -------------------------------------------------------------------------------- 1 | SEARCHINGVALUE) { 37 | $lastIndex = $centerIndex - 1; 38 | } 39 | } while($firstIndex <= $lastIndex); 40 | 41 | if (!$isFind) { 42 | echo '見つかりませんでした。'; 43 | } 44 | 45 | $endTime = microtime(true); 46 | $deltaTime = $endTime - $startTime; 47 | echo('
処理にかかった時間は' . $deltaTime . 'ミリ秒です'); -------------------------------------------------------------------------------- /src/search/boyerMooreSearch.php: -------------------------------------------------------------------------------- 1 | '; 15 | //②最初でマッチ 16 | var_dump(bMSearch('テストトテストトトト', 'テストトテスト')); //true 17 | echo '
'; 18 | //③途中でマッチ 19 | var_dump(bMSearch('テストトテストストトテストテテテテテ', 'テストトテスト')); //true 20 | echo '
'; 21 | //④途中でマッチ 22 | var_dump(bMSearch('aaaabdfdsrtatテストトテストストトテストテ', 'テストトテスト')); //true 23 | echo '
'; 24 | //⑤最後でマッチ 25 | var_dump(bMSearch('テストトテテストトテスト', 'テストトテスト')); //true 26 | echo '
'; 27 | //⑥最後でマッチ2 28 | var_dump(bMSearch('テストトテnトテストトテスト', 'テストトテスト')); //true 29 | echo '
'; 30 | //⑦最後でマッチ3 31 | var_dump(bMSearch('テストトテスnテストトテスト', 'テストトテスト')); //true 32 | echo '
'; 33 | //⑧見つけたい文字よりも短い 34 | var_dump(bMSearch('テスト', 'テストトテスト')); //false 35 | echo '
'; 36 | //⑨一致しない 37 | var_dump(bMSearch('テストトテス', 'テストトテスト')); //false 38 | echo '
'; 39 | //⑩一致しない 40 | var_dump(bMSearch('後戻りを考慮せず無限ループではまる', 'テストトテスト')); //false 41 | 42 | function bMSearch($text, $pattern) { 43 | $tLength = mb_strlen($text); //テキストの長さ 44 | $pLength = mb_strlen($pattern); //パターンの長さ 45 | $shifTable = array(); //シフトする量のマスタテーブル 46 | 47 | //シフトテーブルの作成。末尾の1個前まで実施 48 | for ($i = 0; $i < $pLength - 1; $i++) { 49 | //キーはパターンの文字。値はシフト量 50 | $shifTable[mb_substr($pattern, $i, 1, 'UTF-8')] = $pLength - $i -1; 51 | } 52 | //パターンの末尾のみの計算。もし、既に文字がある場合は何もしない。最初のfor分でやるとシフト量が0になるため 53 | if (!array_key_exists(mb_substr($pattern, $pLength-1, 1, 'UTF-8'), $shifTable)) { 54 | $shifTable[mb_substr($pattern, $pLength-1, 1, 'UTF-8')] = $pLength; 55 | } 56 | 57 | //var_dump($shifTable); 58 | //exit(''); 59 | //探索する 60 | //テキストのindexをパターンの末尾とあわせる。末尾から探索していく 61 | $tIndex = $pLength -1; 62 | while ($tIndex < $tLength) { 63 | //パターンの末尾位置 64 | $pp = $pLength - 1; 65 | //文字が一致している間実施 66 | while (mb_substr($text, $tIndex, 1, 'UTF-8') == mb_substr($pattern, $pp, 1, 'UTF-8')) { 67 | if ($pp == 0) { 68 | //探索成功 69 | return true; 70 | } 71 | $tIndex--; 72 | $pp--; 73 | } 74 | //移動する 75 | if (isset($shifTable[mb_substr($text, $tIndex, 1, 'UTF-8')])) { 76 | //後戻り対策。大きい方を取る 77 | $tIndex = $tIndex + MAX($shifTable[mb_substr($text, $tIndex, 1, 'UTF-8')], $pLength - $pp); 78 | } else { 79 | //パターン以外の文字の時 80 | $tIndex = $tIndex + $pLength; 81 | } 82 | } 83 | //探索失敗 84 | return false; 85 | } 86 | -------------------------------------------------------------------------------- /src/search/chainHashSearch.php: -------------------------------------------------------------------------------- 1 | add(1); 22 | $chainHashBox->add(2); 23 | $chainHashBox->add(3); 24 | $chainHashBox->add(4); 25 | $chainHashBox->add(5); 26 | $chainHashBox->add(6); 27 | $chainHashBox->add(7); 28 | $chainHashBox->add(8); 29 | $chainHashBox->add(9); 30 | $chainHashBox->add(10); 31 | $chainHashBox->add(15); 32 | $chainHashBox->add(25); 33 | 34 | echo '
';
35 | $list = $chainHashBox->getList();
36 | var_dump($list);
37 | echo '
'; 38 | 39 | echo '探索テスト
'; 40 | echo '1の探索テスト
'; 41 | $searchingValue = 1; 42 | $key = $chainHashBox->search($searchingValue); 43 | if ($key) { 44 | echo $searchingValue . 'はlist[' . $key . ']に格納されています。'; 45 | var_dump($list[$key]); 46 | } 47 | echo '
'; 48 | 49 | echo '5の探索テスト
'; 50 | $searchingValue = 5; 51 | $key = $chainHashBox->search($searchingValue); 52 | if ($key) { 53 | echo $searchingValue . 'はlist[' . $key . ']に格納されています。'; 54 | var_dump($list[$key]); 55 | } 56 | echo '
'; 57 | 58 | echo '15の探索テスト
'; 59 | $searchingValue = 15; 60 | $key = $chainHashBox->search($searchingValue); 61 | if ($key) { 62 | echo $searchingValue . 'はlist[' . $key . ']に格納されています。'; 63 | var_dump($list[$key]); 64 | } 65 | echo '
'; 66 | 67 | echo '25の探索テスト
'; 68 | $searchingValue = 25; 69 | $key = $chainHashBox->search($searchingValue); 70 | if ($key) { 71 | echo $searchingValue . 'はlist[' . $key . ']に格納されています。'; 72 | var_dump($list[$key]); 73 | } 74 | echo '
'; 75 | 76 | echo '100の探索テスト
'; 77 | $searchingValue = 100; 78 | $key = $chainHashBox->search($searchingValue); 79 | if ($key) { 80 | echo $searchingValue . 'はlist[' . $key . ']に格納されています。'; 81 | var_dump($list[$key]); 82 | } else { 83 | echo '値はありません。'; 84 | } 85 | echo '
'; 86 | 87 | echo '
'; 88 | -------------------------------------------------------------------------------- /src/search/linearSearch.php: -------------------------------------------------------------------------------- 1 | 処理にかかった時間は' . $deltaTime . 'ミリ秒です'); -------------------------------------------------------------------------------- /src/sevenPuzzleTest.php: -------------------------------------------------------------------------------- 1 | saveHistory($firstValue,-1); 22 | 23 | $endIndex = $savenPuzzle->solveSevenPuzzle(); 24 | $savenPuzzle->showAnswer($savenPuzzle->history[$endIndex], $endIndex); 25 | -------------------------------------------------------------------------------- /src/shintyokuhadoudesuka.php: -------------------------------------------------------------------------------- 1 | 2 && 18 | $words[$n] == 'か' && 19 | $words[$n-1] == 'です' && 20 | $words[$n-2] == 'どう' && 21 | $words[$n-3] == '進捗' 22 | ) { 23 | break; 24 | } 25 | $n++; 26 | } 27 | 28 | echo '???'; 29 | echo '
'; 30 | echo (mb_strlen(implode('', $words), 'UTF-8')) . ' 文字で煽られた'; 31 | 32 | -------------------------------------------------------------------------------- /src/sort/bubbleSort.php: -------------------------------------------------------------------------------- 1 | $sortedCount; $index--) { 24 | if($list[$index - 1] > $list[$index]) { 25 | //1個前の要素の方が大きい時、自分のと1個前の値を交換する 26 | $tmp = $list[$index-1]; 27 | $list[$index - 1] = $list[$index]; 28 | $list[$index] = $tmp; 29 | 30 | $last = $index; 31 | } 32 | } 33 | //ソート済の個数を記憶 34 | $sortedCount = $last; 35 | echo $sortedCount . '個昇順にソート済'; //既にソートされている場合は表示されない 36 | echo '
'; 37 | } 38 | 39 | echo '

ソート完了

'; 40 | echo '
';
41 | var_dump($list);
42 | echo '
'; 43 | -------------------------------------------------------------------------------- /src/sort/insertionSort.php: -------------------------------------------------------------------------------- 1 | '; 16 | var_dump($list); 17 | echo ''; 18 | 19 | $listCount = count($list); 20 | 21 | for($sortedCount = 1; $sortedCount < $listCount; $sortedCount++ ) { 22 | //挿入する値を保存 23 | $tmp = $list[$sortedCount]; 24 | //ソート位置を探す 25 | //$indexは減少していく数で1以上であることかつ挿入する値よりも値が大きい時for文の中身が実施される 26 | for($index= $sortedCount; $index >= 1 && $list[$index - 1] > $tmp; $index--) { 27 | //1個ずらして保存 28 | $list[$index] = $list[$index - 1]; 29 | } 30 | //ソート位置が決まったら挿入 31 | //var_dump($index); //for文の中で使われたindexの値-1がこのindex 32 | $indexMinusOne = $index; 33 | $list[$indexMinusOne] = $tmp; 34 | } 35 | 36 | echo 'ソート完了'; 37 | echo '
';
38 | foreach ($list as $value) {
39 |     echo $value;
40 |     echo '
'; 41 | } 42 | echo '
'; -------------------------------------------------------------------------------- /src/sort/mergeSort.php: -------------------------------------------------------------------------------- 1 | '; 17 | var_dump($list); 18 | echo ''; 19 | 20 | $listCount = count($list); 21 | 22 | mergeSort($list,0, $listCount-1); 23 | 24 | echo 'ソート完了'; 25 | echo '
';
26 | foreach ($list as $value) {
27 |     echo $value;
28 |     echo '
'; 29 | } 30 | echo '
'; 31 | 32 | function mergeSort(&$list, $first, $last) { 33 | 34 | if ($first < $last) { //実施条件(分割できる事。)これがないと再帰が終わらない。 35 | $center = intval(($first + $last) / 2); 36 | $p = 0; 37 | $j = 0; 38 | $k = $first; 39 | $tmp = null; //待避配列 40 | 41 | //前半部分をソートする 42 | mergeSort($list, $first, $center); 43 | //後半部分をソートする 44 | mergeSort($list, $center + 1, $last); 45 | 46 | //ここから前半部分と後半部分を比較して一つにする 47 | 48 | //ソート済みの前半部分を待避配列に全て保存する 49 | for ($i = $first; $i <= $center; $i++) { 50 | $tmp[$p++] = $list[$i]; 51 | } 52 | 53 | //$iが対象配列の最後まで行って、$tmp配列を全て調べ終わるまで行う 54 | //$iは$center + 1から。つまり右側と左側($tmp)の比較 55 | //$pも$center + 1。 56 | //$jは0から 57 | //$kも0から (再帰で使う時は$first) 58 | while ($i <= $last && $j < $p) { 59 | if ($tmp[$j] <= $list[$i]) { 60 | //前半部分の配列が後半部分よりも小さい時 61 | //そのまま対象配列に前半部分の値を保存 62 | $list[$k] = $tmp[$j]; 63 | //ポインタは各々増やす 64 | $k++; 65 | $j++; 66 | } else { 67 | //後半部分のほうが小さい時 68 | //対象配列に後半部分の値を入れる。 69 | //前半部分の配列は$tmp配列にコピーしているので上書きでOK 70 | $list[$k] = $list[$i]; 71 | //ポインタを各々増やす 72 | $k++; 73 | $i++; 74 | } 75 | } 76 | 77 | //余っている待避配列があれば、全て並び替えの対象配列に追加する 78 | while ($j < $p) { 79 | $list[$k++] = $tmp[$j++]; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/sort/quickSort.php: -------------------------------------------------------------------------------- 1 | '; 16 | var_dump($list); 17 | echo ''; 18 | 19 | $listCount = count($list); 20 | 21 | quickSort($list,0, $listCount-1); 22 | 23 | echo 'ソート完了'; 24 | echo '
';
25 | foreach ($list as $value) {
26 |     echo $value;
27 |     echo '
'; 28 | } 29 | echo '
'; 30 | 31 | function quickSort(&$list, $first, $last) { 32 | $firstPointer = $first; 33 | $lastPointer = $last; 34 | //枢軸値を決める。配列の中央値 35 | $centerValue = $list[intVal(($firstPointer + $lastPointer) / 2)]; 36 | 37 | //並び替えができなくなるまで 38 | do { 39 | //枢軸よりも左側で値が小さい場合はポインターは進める 40 | while ($list[$firstPointer] < $centerValue) { 41 | $firstPointer++; 42 | } 43 | //枢軸よりも右側で値が大きい場合はポインターを減らす 44 | while ($list[$lastPointer] > $centerValue) { 45 | $lastPointer--; 46 | } 47 | //この操作で左側と右側の値を交換する場所は特定 48 | 49 | if ($firstPointer <= $lastPointer) { 50 | //ポインターが逆転していない時は交換可能 51 | $tmp = $list[$lastPointer]; 52 | $list[$lastPointer] = $list[$firstPointer]; 53 | $list[$firstPointer] = $tmp; 54 | //ポインタを進めて分割する位置を指定 55 | $firstPointer++; 56 | $lastPointer--; 57 | } 58 | } while ($firstPointer <= $lastPointer); 59 | 60 | if ($first < $lastPointer) { 61 | //左側が比較可能の時 62 | quickSort($list, $first, $lastPointer); 63 | } 64 | 65 | if ($firstPointer < $last) { 66 | //右側が比較可能時 67 | quickSort($list, $firstPointer, $last); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/sort/selectionSort.php: -------------------------------------------------------------------------------- 1 | '; 15 | var_dump($list); 16 | echo ''; 17 | 18 | $listCount = count($list); 19 | $isChange = false; 20 | 21 | for($sortedCount = 0; $sortedCount < $listCount; $sortedCount++ ) { 22 | //最小値のキーの変数を定義。まずは基準位置をセットする 23 | $minKey = $sortedCount; 24 | //最小値を探す 25 | for ($index = $sortedCount +1; $index < $listCount; $index++) { 26 | if ($list[$index] < $list[$sortedCount]) { 27 | $minKey = $index; 28 | $isChange = true; 29 | } 30 | if ($isChange) { 31 | //最小値が変わったら 32 | $tmp = $list[$sortedCount]; 33 | $list[$sortedCount] = $list[$minKey]; 34 | $list[$index] = $tmp; 35 | $isChange = false; 36 | } 37 | } 38 | } 39 | 40 | echo 'ソート完了'; 41 | echo '
';
42 | foreach ($list as $value) {
43 |     echo $value;
44 |     echo '
'; 45 | } 46 | echo '
'; -------------------------------------------------------------------------------- /src/sort/shellSort.php: -------------------------------------------------------------------------------- 1 | '; 18 | var_dump($list); 19 | echo ''; 20 | 21 | $listCount = count($list); 22 | //まず最初にとびとびの間隔を決める 23 | $step = 1; 24 | for($step_tmp = 1; $step_tmp < $listCount / 9; $step_tmp = $step_tmp * 3 + 1 ){ 25 | $step = $step_tmp; 26 | } 27 | 28 | while($step > 0 ){ 29 | //最初は離れたところで交換。次第に細かく。 30 | for($index = $step; $index < $listCount; $index++ ){ 31 | $tmp = $list[$index]; 32 | //考え方は挿入ソートとほぼ同じ。離れた相手と比較するだけ 33 | for($j = $index - $step; $j >= 0 && $list[$j] > $tmp; $j = $j - $step ){ 34 | $list[$j + $step ] = $list[$j]; 35 | } 36 | $list[$j + $step] = $tmp; 37 | } 38 | $step = (int) ($step / 3); 39 | } 40 | 41 | echo 'ソート完了'; 42 | echo '
';
43 | foreach ($list as $value) {
44 |     echo $value;
45 |     echo '
'; 46 | } 47 | echo '
'; -------------------------------------------------------------------------------- /src/tree/binaryTreeTest.php: -------------------------------------------------------------------------------- 1 | value = 1000; 12 | BinaryTree::insertNode(2000, $tree); 13 | BinaryTree::insertNode(300, $tree); 14 | BinaryTree::insertNode(4000, $tree); 15 | BinaryTree::insertNode(5000, $tree); 16 | BinaryTree::insertNode(100, $tree); 17 | BinaryTree::insertNode(50, $tree); 18 | BinaryTree::insertNode(10, $tree); 19 | BinaryTree::insertNode(200, $tree); 20 | BinaryTree::insertNode(400, $tree); 21 | echo '
';
22 | var_dump($tree);
23 | echo '
'; 24 | 25 | echo '
'; 26 | echo 'ここから検索テスト'; 27 | var_dump(BinaryTree::find(1000, $tree)); 28 | var_dump(BinaryTree::find(2000, $tree)); 29 | var_dump(BinaryTree::find(300, $tree)); 30 | var_dump(BinaryTree::find(4000, $tree)); 31 | var_dump(BinaryTree::find(5000, $tree)); 32 | var_dump(BinaryTree::find(100, $tree)); 33 | var_dump(BinaryTree::find(50, $tree)); 34 | var_dump(BinaryTree::find(10, $tree)); 35 | var_dump(BinaryTree::find(200, $tree)); 36 | var_dump(BinaryTree::find(400, $tree)); 37 | var_dump(BinaryTree::find(1, $tree)); 38 | echo '
'; 39 | echo 'ここから消去テスト'; 40 | var_dump(BinaryTree::delete(1, $tree)); 41 | echo '
'; 42 | //リーフの削除テスト 43 | //var_dump(BinaryTree::delete(400, $tree)); 44 | //右のノードしかない時の削除テスト 45 | //var_dump(BinaryTree::delete(2000, $tree)); 46 | //左のノードしかない時の削除テスト 47 | //var_dump(BinaryTree::delete(50, $tree)); 48 | //右と左のノードがある時のテスト 49 | //var_dump(BinaryTree::delete(300, $tree)); 50 | //右と左のノードがある時のテスト 51 | ////var_dump(BinaryTree::delete(100, $tree)); 52 | //ルートの削除テスト 53 | //var_dump(BinaryTree::delete(1000, $tree)); 54 | //木を左のノードしかないようにしてルートを削除 55 | //木を右のノードにしてルートを削除 56 | var_dump(BinaryTree::delete(1000, $tree)); 57 | 58 | echo '
';
59 | var_dump($tree);
60 | echo '
'; --------------------------------------------------------------------------------