PHP初学者のためのフィボナッチ数列の問題と解答

このQ&Aのポイント
  • PHPの勉強を初めて間もない初学者が、参考書に出ているフィボナッチ数列の問題について質問です。
  • 質問文章の中で演習問題の内容と解答を示しており、自己解決できない性格上、解答の確認と説明をお願いしています。
  • 質問者はフィボナッチ数列を計算するスクリプトをfor文やwhile文を使って実装し、フィボナッチ数列の値が1000億を超えるのは第何項かを調べるスクリプトも作成しています。
回答を見る
  • ベストアンサー

初めて質問させて頂きます。長文失礼します。

初めて質問させて頂きます。長文失礼します。 最近、PHPの勉強を初めまして、”かんたんプログラミングPHP(著:久松慎一)” という参考書かたてにやり始めて間もないのですが、その本の中にて、基本となる 構文やデータ型、変数や定数、更に、演算子や制御構文についての簡単な説明を読ん だところで、演習問題が出ているのですが、どこにも、その模範となる解答が書かれ ておらず、自己解決して下さいといった感じで、次の章である”関数の利用”に飛ん でしまいます。出来ないものを飛ばして次に進むことが出来ない性格上(特にゼロか らの学習の為うやむやのままが気持ち悪いです。)、この演習問題を突破したく質問 させて頂きました。 ネット上にて、いくつかの作成例を見てきたのですが、とても参考書のそれまでの説明 だけで理解出来るものではありませんでした。 とりあえず、自分で何とか分かる範囲で作ったものがあるのですが、これでも大丈夫な ものかご教授願えたらと思います。 こんなん飛ばして、もっと理解を深めてからにした方が良いということであれば、参考 にさせて頂きたいと思います。 以下に演習として出されている問題と私の解答を載せますのでどうぞご指導ください。 --------------------------------------------------------------------------------- ■フィボナッチ数列  (1) for文または while文を使って 50項までのフィボナッチ数列を計算する  スクリプトを書いてください。(ただし、1つ目と2つ目の項は必ず1)  (2) フィボナッチ数列の値が 100000000000(1000億)を超えるのは第何項になる  か調べるスクリプトを書いてください。 <(1)についての解答> <?php $n = 50; //* 項目数 *// for($total = 1 , $box = array(0,1) , $i = 1 , $sta = 1; $i < $n ; $i++){ $sta = $box[$i] + $box[($i-1)]; array_push($box,$sta); $total = $total + $sta; //* ついでに今までの数の和を求める式 *// } echo "第50項目の答えは、$sta です。" ; echo "それまでの数の合計は、$total です。" ; ?> <(2)についての解答> <?php $n = 100000000000; //* 任意のフィボナッチ数列の値 *// for($total = 1 , $box = array(0,1) , $i = 1 , $sta = 1; $sta < $n+1 ; $i++){ $sta = $box[$i] + $box[($i-1)]; array_push($box,$sta); } echo "100000000000を超える数値の項は、第 $i 項目です。" ; ?> --------------------------------------------------------------------------------- 以上になります。 記載させて頂きました通りの初心者になります。 もし、こんな私にでも分かる説明をして下さる方いらっしゃいましたら どうぞ宜しくお願いいたします。

  • PHP
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

> <(1)についての解答>  50番目の項目を求めるという問題なら間違ってはいませんが、単に50項までのフィボナッチ数列を求めるという問題なら第1項から第50項までの数列を出力する必要があるように思います。 > <(2)についての解答>  for文は    for(A; B; C;) {      // 処理    } とあった時、  ループの最初にAが実行され、次に各回の最初にBが評価され、処理が終わったループの最後でCが実行されます。  つまり、($i番目の処理結果としての)ループの終了判定 $sta < $n+1 が評価される前に $i++で$iはインクリメントされてしまっています。つまり、上のプログラムでは実際に100000000000を超えた時の項目番号より一つ大きな値の$iが出力されてしまいます。 (正解は54番目だけど、55番目と表示されます)

prototype00
質問者

お礼

<(1)について> 確かに、50項までの数列を出力するというのを勝手に 50番目の項目を求めるものとして作っていました。 ご指摘ありがとうございます!また新たに作り直してみたいと思います。 <(2)について> ループの終了判定 $sta < $n+1 が評価される前に $i++で$iはインクリ メントされてしまうとは知りませんでした・・・。 とても参考になります。  どちらも大変分かり易い説明で、また一つ、プログラムについての 理解が深まりました。  このような初歩的質問にお時間を割いて頂き本当にありがとうございました!

その他の回答 (1)

  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.1

PHPの練習にはならないけど、フィボナッチ数列の 一般項は近似式で検算できるそうな。 第n項目の答えは、 $n=n+1.0; floor(pow(1.61803398874989484820,$n)/sqrt(5.0)+0.5); だそうな。 ※1.61803398874989484820は黄金比

参考URL:
http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0%E5%88%97
prototype00
質問者

お礼

フィボナッチ数列について、詳しく調べて頂きありがとうございます! 早速、参考URLの方も拝見しました。が・・・ 難しい!!(^_^;) なんとなく、回答してくださった構文がどれとどれにあたるかは分かったの ですが、如何せん近似式がどういうものかしっかりとまだつかみきれていな い為、今後、しっかりと勉強した上で”yyr446”さんの教えて下さった今回 の制御構文を見直し、そのとき完全に理解してみたいと思います! このような質問にお時間を割いて頂きありがとうございました。

関連するQ&A

  • フィボナッチ数列の配列について

    public class Fibonacci { public static void main(String[] args) { int [] fibAray = new int [20]; //フィボナッチ数列用の配列 fibAray[4] = 3; fibAray[1] = 1; for (int i = 0; i < fibAray.length; i++) { fibAray[i] = i + 1; } for (int i = 0; i < fibAray.length; i++) { System.out.println( "第" + (i + 1) + "頁は" + 3); } } } フィボナッチ数列の第20項までを配列にし、それらを"第4項は3"のように表示する。 という問題で作ったプログラムですが1項~20項まで3と表示されます。 これで合ってるのでしょうか?

    • ベストアンサー
    • Java
  • フォームを使った配列変数の受け渡し

    PHP初心者です、よろしくお願いします。 フォームからPHPで配列変数を受け渡すことを考えています。 一次元配列はうまく渡せましたので、これを二次元にしましたところ、 うまく渡せません。基本的なPHPの文法がわかってないので、つまづい ています。多分、配列変数の記述方法がおかしいのだと思うのですが・・。 ご教授よろしくお願いします。 <html> <body> <form method = "POST" action ="test2.php" > <?php //データ渡し側 for ($i = 0 ;$i < 2 ;$i ++){ for ($j=0 ;$j <2;$j ++ ){ echo ("<input type ='text' name = 'data[$i][$j]' size ='10'>\n"); echo ("<br>\n"); } echo ("</tr>\n"); } ?> <input type="submit" name ="sbmit" value="data_input" > </form> </body> </html> <?php //データ受け側 for ($i = 0 ;$i < 2 ;$i ++){ for ($j=0 ;$j < 2;$j ++ ){ $tmp_data[$i][$j] = $_POST["data"][$i][$j]; echo ("$tmp_data[$i][$j] <br>\n"); } } ?> <html> <body> <form method = "POST" action ="test2.php" > <?php for ($i = 0 ;$i < 2 ;$i ++){ for ($j=0 ;$j <2;$j ++ ){ echo ("<input type ='text' name = 'data[$i][$j]' size ='10' value='$tmp_data[$i][$j]'>\n"); echo ("<br>\n"); } } ?> </table> <input type="submit" name ="sbmit" value="in" > </form> </body> </html> 実行結果は、 Array[0] Array[1] Array[0] Array[1] と表示されて、実際の入力した値が反映されません。

    • ベストアンサー
    • PHP
  • PHPでのページング処理についての質問です。

    ドットインストールにてページングの勉強をしています。 http://dotinstall.com/lessons/paging_php_v2/8510 件数が多いと、 この場合ですと10ページ以上まで表示されてしまうかと思うのですが、 よくあるWEBサービスのように10ページまでで区切り、 10ページ目をクリックすると、 5ページから15ページまでを表示させたいのですが、 どのように書いていくものでしょうか? <?php define('DB_HOST', 'localhost'); define('DB_USER', 'dbuser'); define('DB_PASSWORD', '********'); define('DB_NAME', 'dotinstall_paging_php'); define('COMMENTS_PER_PAGE', 5); if (preg_match('/^[1-9][0-9]*$/', $_GET['page'])) { $page = (int)$_GET['page']; } else { $page = 1; } error_reporting(E_ALL & ~E_NOTICE); try { $dbh = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME,DB_USER,DB_PASSWORD); } catch (PDOException $e) { echo $e->getMessage(); exit; } // select * from comments limit OFFSET, COUNT // page offset count // 1 0 5 // 2 5 5 // 3 10 5 // 4 15 5 $offset = COMMENTS_PER_PAGE * ($page - 1); $sql = "select * from comments limit ".$offset.",".COMMENTS_PER_PAGE; $comments = array(); foreach ($dbh->query($sql) as $row) { array_push($comments, $row); } $total = $dbh->query("select count(*) from comments")->fetchColumn(); $totalPages = ceil($total / COMMENTS_PER_PAGE); // var_dump($comments); // exit; $from = $offset + 1; $to = ($offset + COMMENTS_PER_PAGE) < $total ? ($offset + COMMENTS_PER_PAGE) : $total; ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>コメント一覧</title> </head> <body> <h1>コメント一覧</h1> <p>全<?php echo $total; ?>件中、<?php echo $from; ?>件~<?php echo $to; ?>件を表示しています。</p> <ul> <?php foreach ($comments as $comment) : ?> <li><?php echo htmlspecialchars($comment['comment'],ENT_QUOTES,'UTF-8'); ?></li> <?php endforeach; ?> </ul> <?php if ($page > 1) : ?> <a href="?page=<?php echo $page-1; ?>">前</a> <?php endif; ?> <?php for ($i = 1; $i <= $totalPages; $i++) : ?> <?php if ($page == $i) : ?> <strong><a href="?page=<?php echo $i; ?>"><?php echo $i; ?></a></strong> <?php else: ?> <a href="?page=<?php echo $i; ?>"><?php echo $i; ?></a> <?php endif; ?> <?php endfor; ?> <?php if ($page < $totalPages) : ?> <a href="?page=<?php echo $page+1; ?>">次</a> <?php endif; ?> </body> </html>

    • ベストアンサー
    • PHP
  • PHP4で、メンバ変数の値を忘れてしまう2

    PHP4での質問です。 前の質問がわかりにくかったので、書き直しました。 オブジェクト指向的にいかがなものかとは思いますが、オブジェクトのメンバ変数を直接外部から変更したいと思います。 ---------<a.php>---------- class myClass {   var member = 0; } ---------<b.php>---------- $ary_c = array(); for ($i=0; $i<10; $i++) {   $c = new myClass();   $c->member = 1;   echo "(1)c->member=".$c->member;   array_push($ary_c, $c); } foreach ($ary_c as $c) {   echo "(2)c->member=".$c->member; } ------------------------------ 以上の様なソースで、(1)のデバッグライトでは、メンバ変数memberの値は1であるのに、(2)のデバッグライトでは、0になってしまいます。 この原因がお分かりのかた、もしよろしければ知恵をお貸し下さい。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • 数列の収束

    次のような問題です。 a_1=1,a_n+1=1/(1+a_n)の漸化式で定まる数列を考える。 このとき数列a_nが収束することを示せ。 こんな問題なのですが、分かりそうでわかりません。 実際、順に書き並べていくと分子・分母がフィボナッチ数列になり一般項は求められないこともないですが、複雑すぎてここから収束性を示すのは難しいと思います。 また、この数列は有界なことは分かりましたが単調数列じゃないので収束性は示せませんし・・・ だれか分かるかたいましたら解答お願いします。

  • Pascal言語

    フィボナッチ数列の項は、その直前の連続する二つの項の和である。 f( n ) = f( n - 1 ) + f( n - 2 ) 但し、 f(0) = 0, f(1) = 1 である。   フィボナッチ数列の連続する項の差の比 z = { f( n - 1 ) - f( n - 2 ) }/ { f( n ) - f( n - 1 ) } は、 n が大きくなれば、ある値に収束する。この値の近似値を求める プログラムを書き、その値を示せ。この値は黄金分割比と呼ばれる。 フィボナッチ数列は関数 fibonacci を作って求め、項は配列に表せ。まず 30 項まで求め、黄金分割比の値が収束していく様子を出力して確かめよ。収束判定のために定数 dif = 1.0 e -6 を宣言し、 連続する z の差の絶対値が dif 以下になったとき、収束したとして計算を終了するプログラムを作りなさい。 この問題について質問なんですが コンパイルはできるんだけど、結果がうまく表示されません。 すみませんがわかる方教えてくれませんか? program pe1_2(input,output); const dif = 1.0e-6; var i,m, g : integer; f, z,q : array [0..500] of real; function fibonacci(n: integer):integer; begin if (n >=0) and (n <=1) then fibonacci:=n else fibonacci:=fibonacci(n-1)+fibonacci(n-2); end; { fibonacci } begin f[i]:=fibonacci(i); writeln('30項まで求めます '); for i :=1 to 30 do begin writeln('f(',i:2,')=',f[i]:1); end; write('m='); readln(m); for i:= 3 to m do repeat z[i]:=(f[i-1]-f[i-2])/(f[i]-f[i-1]); until dif >= z[i]-z[i-1]; writeln(z[i]); {writeln('z(',i:3,')=',z[i]:1,','); } end.

  • 値の引継ぎについて

    下記のスクリプトについてなのですが… <?php $data=array("1","2","3","4","5","6","7","8","9","10","11","12"); for($i = 0; $i < 3; $i ++){ $index = fopen("$i.php", "w"); for($n = 0; $n < 4; $n ++){ fwrite($index,$data[$n]); } fclose($index); } for($i = 0; $i < 3; $i++){ echo "<a href=\"./$i.php\">$i</a><br>"; } ?> 0.php、1.php、2.phpのファイルができるのですが、1で表示されるのが5~8、2で表示されるのが9~12となるにはどのようにしたら良いでしょうか?

    • ベストアンサー
    • PHP
  • 配列のループ展開

    下記で配列内を検索しても、「存在しません」になります。 どこが、間違っているのでしょうか? <?php for($i = 1; $i <= 42; $i++) { $seminar = "http://www.hoge.com/hoge/".sprintf("%04d", $i).".html"; echo $seminar; } $url = array( $seminar ); $myUrl = "http://www.hoge.com/hoge/0020.html"; if(in_array($myUrl, $url)){ echo "配列に".$myUrl."は存在します。"; } else { echo "配列に".$myUrl."は存在しません。"; } ?>

    • ベストアンサー
    • PHP
  • 2つの変数(文字)を組み合わせて1つの変数として認識させる方法?

    PHPの初心者チュートリアルサイトやphp manualなども見てるのですが あまりに基本的過ぎるのか、どうしてもわからないので教えてください。 $myarray1 = array("a","b","c"); $myarray2 = array("d","e","f"); $myarray3 = array("x","y","z"); という配列があるとして、 これをforループで使いたいと考えました。 例えば無理やり書くと下記のようなイメージなのですが やはりこのようなあてずっぽうではうまく行かず・・・。 for( $i = 1; $i<= 3; $i++ ){ echo {$myarray.$i}[0] . "<br/>"; } 「$myarray.$i」を$myarray1~3と認識させてa,d,xの3つを出力することはできますか?

    • 締切済み
    • PHP
  • AJAX+PHPでセレクトボックスの連動

    AJAX+PHPでセレクトボックスの連動をしようとしています。 function SelAjax(){ var x = $('#category1').val(); $.ajax({ type: "POST", url: "category.php", data: {"prm":x}, dataType: "json", success: function(data, status){ $.each(data,function(i) { $('#category2').append($('<option>').attr({ value: i }).text(data[i])); }); }, error: function(XMLHttpRequest, status, errorThrown){ alert("エラーが発生しました!"); } }); } としています。 PHP側で $CATEGORY2 = array( 1 => array( 1 => "a", 2 => "b", 3 => "c", 4 => "d", ), 2 => array( 1 => "e", 2 => "f", 3 => "g", 4 => "h", ), 3 => array( 1 => "i", 2 => "j", 3 => "k", 4 => "l", ), 4 => array( 1 => "m", 2 => "n", 3 => "o", 4 => "p", ), 5 => array( 1 => "q", 2 => "r", ), 6 => array( 1 => "s", 2 => "t", 3 => "u", ), ); $ary = array(); if($_POST["prm"]){ for($i=1;$i<=6;$i++){ if($i ==$_POST["prm"] ) $ary = $CATEGORY2[$i]; } } echo json_encode($ary); としています。 一回目に1番目のセレクトボックスを選択してAjaxでPOSTし2つ目のセレクトボックスを生成できました。 しかし、2回目として1番目のセレクトボックスを選択した際に、1回目にPHPから受け取った配列に積みあがってしまいます。 どのように対処すればいいかわかりません。 教えてください。

    • ベストアンサー
    • AJAX

専門家に質問してみよう