<?php /****************************/ /* ソートと探索 */ /* coded by Y.Suganuma */ /****************************/ // // 二分探索 // function b_search($key, $data, $n) { $sw = -1; $left = 0; $right = $n - 1; if ($data[$right] > $data[$left]) { while ($left < $right) { $center = floor(($left + $right) / 2); if ($data[$center] < $key) $left = ($center < $n-1) ? $center + 1 : $center; else $right = $center; } } else { while ($left < $right) { $center = floor(($left + $right) / 2); if ($data[$center] > $key) $left = ($center < $n-1) ? $center + 1 : $center; else $right = $center; } } if ($data[$left] == $key) $sw = $left; return $sw; } // 初期設定 mt_srand(); // // 探索(配列) // // データ設定 $N = 1000000; $NS = 100000; $data = array(); $data_s = array(); $tm1 = microtime(); $ms = strtok($tm1, " "); $sec = strtok(" "); $tm1 = (intval($sec) % 1000) * 1000 + intval(floatval($ms) * 1000); $m = 0; for ($i1 = 0; $i1 < $N; $i1++) { $k = mt_rand(0, 2000000000); $data[$i1] = $k; if ($i1%10 == 0) { $data_s[$m] = $k; $m++; } } // sort $tm2 = microtime(); $ms = strtok($tm2, " "); $sec = strtok(" "); $tm2 = (intval($sec) % 1000) * 1000 + intval(floatval($ms) * 1000); sort($data); // 探索 $tm3 = microtime(); $ms = strtok($tm3, " "); $sec = strtok(" "); $tm3 = (intval($sec) % 1000) * 1000 + intval(floatval($ms) * 1000); $n = 0; for ($i1 = 0; $i1 < $NS; $i1++) { if (!in_array($data_s[$i1], $data)) $n++; } // 二分探索 $tm4 = microtime(); $ms = strtok($tm4, " "); $sec = strtok(" "); $tm4 = (intval($sec) % 1000) * 1000 + intval(floatval($ms) * 1000); $n = 0; for ($i1 = 0; $i1 < $NS; $i1++) { if (b_search($data_s[$i1], $data, $N) < 0) $n++; } $tm5 = microtime(); $ms = strtok($tm5, " "); $sec = strtok(" "); $tm5 = (intval($sec) % 1000) * 1000 + intval(floatval($ms) * 1000); printf("データ数(array): %d,探索データ数 %d\n", $N, $NS); printf(" data %d ms\n", $tm2-$tm1); printf(" sort %d ms\n", $tm3-$tm2); printf(" 探索 %d ms,失敗 %d\n", ($tm4-$tm3), $n); printf(" 二分探索 %d ms,失敗 %d\n", ($tm5-$tm4), $n); // // 文字列( string ) // $N1 = 1000201; $NS1 = 5000; $NL = 200; // データ設定 $data_st = array(); $str = ""; $n = 0; $tm1 = microtime(); $ms = strtok($tm1, " "); $sec = strtok(" "); $tm1 = (intval($sec) % 1000) * 1000 + intval(floatval($ms) * 1000); for ($i1 = 0; $i1 < $N1; $i1++) { $str = $str.chr(mt_rand(65, 123)); if ($n < $NS1 && $i1 >= 2*$NL && ($i1 % $NL) == 0) { $k = $i1 - $NL - $NL / 2 - 1; $s = substr($str, $k, $NL); if ($n % 2 > 0) { // 存在しないデータの作成 $s1 = substr($s, $k, $NL/2); $s1 = $s1."("; $s1 = $s1.substr($s, $NL/2+1, $NL-$NL/2-1); $s = $s1; } $data_st[$n] = $s; $n++; } } // 探索 $tm2 = microtime(); $ms = strtok($tm2, " "); $sec = strtok(" "); $tm2 = (intval($sec) % 1000) * 1000 + intval(floatval($ms) * 1000); $NS1 = $n; $n1 = 0; $n2 = 0; for ($i1 = 0; $i1 < $NS1; $i1++) { if (strstr($str, $data_st[$i1]) == FALSE) $n2++; else $n1++; } $tm3 = microtime(); $ms = strtok($tm3, " "); $sec = strtok(" "); $tm3 = (intval($sec) % 1000) * 1000 + intval(floatval($ms) * 1000); printf("文字数(string): %d,探索データ(数 %d,文字数 %d)\n", $N1, $NS1, $NL); printf(" data %d ms\n", ($tm2-$tm1)); printf(" 探索 %d ms,成功 %d,失敗 %d\n", ($tm3-$tm2), $n1, $n2); /* データ数(array): 1000000,探索データ数 100000 data 186 ms sort 336 ms 探索 103832 ms,失敗 0 二分探索 397 ms,失敗 0 文字数(string): 1000201,探索データ(数 5000,文字数 200) data 28210 ms 探索 462 ms,成功 2500,失敗 2500 */ ?>