├── 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 '' . $i . ' | ';
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 '' . ($i + 1) . '番目の商品まで使用 | ';
47 | for ($napIndex = 1; $napIndex < $this->knapsackCount + 1; $napIndex++) {
48 | echo '' . $napValue[$napIndex]. ' | ';
49 | }
50 | echo '
';
51 | }
52 | echo '
';
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 '
';
--------------------------------------------------------------------------------