課題
下のようなGETポストが渡ってきたと仮定し、それをソート関数を使わずに小さい順に並び替えるという機能をPHPで作る学習で試行錯誤したのでその跡を残しておきたく。
http://localhost:10080/index.php?array=3,2,1,4,15,18,13,99,77,66,1,100,0
バブルソートというアルゴリズムでこれが実現できます。バブルソートとは、一つのループの中にもう一つループを作り、内側のループで隣り合う数字の大小を比較して並び替えていくことで、配列全体を並び替えます。Wikipediaの説明がわかりやすいです。
実装
<?php
$array = explode(',', $_GET['array']); //explode()はExcelの「区切り」みたいなもの
$count = count($array);
for ($i = 0; $i < $count; $i++) {
for ($n = 1; $n < $count; $n++) {
if($array[$n-1] > $array[$n]) {
$temp = $array[$n]; //右隣の方が大きかったらその右の数字を$tempに逃がす
$array[$n] = $array[$n-1]; //左側を右側に代入
$array[$n-1] = $temp; //逃がしていた右側を左側に代入
}
}
}
print_r($array);
?>
アルゴリズムとは関係のない、PHPの復習ですが、$_GET
はPHPの定義済みの変数で、URLで渡されたパラメータ(クエリストリング、クエリ文字列と同義)を受け取ります。参考→URLパラメータ
$_GETにはPHPの関数urldecode()
が処理してから値が渡されるようです。
結果
改善
$n-1
が何回も出てくるのが気になったので、こうしてみました↓
きちんと同じ結果が得られます。
$count = count($array);
for ($i = 0; $i < $count; $i++) {
for ($b = 1; $b < $count; $b++) { //右隣の数字を$bとする
$a = $b-1; //←左隣の数字を$aとする
if($array[$a] > $array[$b]) {
$temp = $array[$b];
$array[$b] = $array[$a];
$array[$a] = $temp;
}
}
}
余談
試行錯誤の跡として、こちらが最初にトライしたコーディングです。配列の中から一番小さい値を探して別の変数に代入し、その値を元の配列から削除するというものです。これだと同じ数が複数個あった場合(今回だと1が2回ある)、その数は1個しか取り出せませんでした。
http://localhost:10080/php-pre-challenge2/index.php?array=3,2,1,4,15,18,13,99,77,66,1,100,0
<?php
$array = explode(',', $_GET['array']);
$sorted_array = [];
$count = 0;
while ($count < count($array)) {
$tmp = null;
foreach ($array as $key => $value) {
if (in_array($value, $sorted_array)) continue;
if ($tmp === null) {
$tmp = $value;
} else {
$tmp = min($tmp, $value);
}
}
$sorted_array[] = $tmp;
$count++;
}
print_r($sorted_array);
?>
ご指摘などあれば、コメントにてお願いします!