第1回 アルゴリズム勉強

実はアルゴリズムが苦手。
特定の数式やルールに則った処理をコードに落としこむことができない。

今まで普段の業務では特に不自由しなかったけど、
それは自分の苦手な分野というか、
苦手なアルゴリズムに当たらなかっただけみたい。

唯一、ディレクトリツリーのファイル検索は
再帰を使って実装したけど、
かなり苦戦したのを覚えている。

さすがに最低限のアルゴリズムは知らないとヤバイ気がしてきたので、
勉強します。


まずは fizzbuzz
このくらいなら問題ない。

<?php

$n = 5;

for($i = 0; $i < $n + 1; $i++){
	if($i == 0){
		echo $i."\n";
	}elseif($i % 3 === 0 && $i % 5 === 0){
		echo 'fizzbuzz'."\n";
	}elseif($i % 3 === 0){
		echo 'fizz'."\n";
	}elseif($i % 5 === 0){
		echo 'buzz'."\n";
	}else{
		echo $i."\n";
	}
}


次にフィボナッチ数列
これができなかった・・・。
「前回の値と前々回の値を加算した値が次の値」という
アルゴリズムは分かるし、
数列を見ればフィボナッチだということも分かる。
が、コードに落としこむことができない。

最初はforとかのループで考えていたけど、うまくいかない。
ググってみると以下がヒットした。

<?php

$a = 1; //前々回の値
$b = 0; //前回の値
$r = 0; //結果

echo "\n\n";

while(($a+$b) <= 13){

	echo 'a = '.$a."\n";
	echo 'b = '.$b."\n";

	$r = ($a+$b);
	
	echo 'r = '.$r."\n\n";
	
	$a = $b;
	$b = $r;
}

なるほど・・・。
$a, $b, $r の3つの変数を利用するところまでは分かったけど、
それぞれを代入するところが分からなかった。
あと、$aの初期値に 1 を設定しているところもポイントだと思う。

自分で書くとしたら以下になる。

<?php

$a = 0; //前々回の値
$b = 1; //前回の値
$r = 0; //結果
$i = 0;

echo "\n\n";

while(($a+$b) <= 13){

	if($i == 0){
		echo 'r = 0'."\n\n";
	}elseif($i == 1){
		echo 'r = 1'."\n\n";
	}else{
		$r = ($a+$b);
		
		echo 'r = '.$r."\n\n";
		
		$a = $b;
		$b = $r;
	}

	$i++;
}

フィボナッチ数列の定義として、
n = 0, n = 1 の時はそれぞれ、0,1 と値が決まっているらしい。
https://ja.wikipedia.org/wiki/フィボナッチ数

なので、それをifで表現する。
$a に 1 を設定するという発想はできない・・・。
難しいな・・・。

で、forで挫折した自分が次に考えたのが、再帰
でも、わからんかった・・・。
ググった結果が以下。

<?php
function func($n){
	if($n<=1) {
	  return $n;
	}else{
    	  return func($n-1)+func($n-2);
	}
}

echo "\n\n".func(5)."\n\n";

return func($n-1)+func($n-2); の部分は分かったんだけど・・・。
「return $n」が分からなかった・・・。



満足に再帰も使えないレベル・・・。
アルゴリズム寄りのスキルが全然ないな・・・。

業務で利用することもあるだろうし、
ちゃんと勉強していこうと思う。