こんにちは､ ようこそ｡
前回の課題である「素数を生成するプログラムを作成する」の解決策をデモで紹介したいと思います｡
また､ このプログラムのポイントは､ 配列を使うことで､
配列のすべてを学び､ これを実行することです｡
そこで､ 以前､ 素数アルゴリズムを説明しようとしたことがあります｡
ただ､ もう一度触れておくと､ 素数が素数であるかどうかは確認することができます｡
素数とは､ 他の素数で均等に割り切れないという意味です｡
それが､ 私たちが目指すコンセプト・アルゴリズムです｡
それがなぜ素数なのかというと､ 素数以外の整数は素因数の倍数で表すことができるからです｡
例えば20は素因数2 2と5を持つわけです｡
つまり､ これを知ることで､ 素数は他の素数で均等に割り切れないことがわかるのです｡
だから､ これは非常に効率的な素数テストを作るのに役立つんだ｡
そこで､ 何ができるかというと､ 以前に生成された素数をチェックすることができるのです｡
そこで､ 以前に生成した素数を配列に格納することで､
この情報を得ることができるのです｡
また､ 任意の9素整数nは､ その因子の1つとしてnの平方根以下の整数を持たなければならない｡
つまり､ ある整数が素数かどうかは､ その整数の平方根までのすべての素因数に対して偶数回割り切れるかどうかを調べればよいことになる｡
だから､ その場で止められるし､ また効率も良くなる｡
これは､ 素数が見つからなかったかどうかを判断するために飛び出す私の内部ループで顕著になりそうです｡
整数の平方根になったら飛び出す､ 本来は終了条件なんだけどね｡
そこで､ pを素数で割った値が素数Iの平方根より大きいかどうかを調べるために､
最も内側のループでこの値を使います｡
では､ さっそくコードブロックを出して､ コードを書き始めてみましょう｡
ここでは基本的なことですが､ プロジェクトを作成します｡
私たちのプロジェクトにprimesという名前をつけることにします｡
では､ 新規プロジェクトで､
コンソールアプリケーションに移動してみましょう｡
そして､ それをプライムと名付けることにしました｡
次に､ このコンパイラは使わないと言ってください｡
コンパイラを弄っていたのですが､ 正しいコンパイラを使いたいので､
cygwinのコンパイラを使うことにします｡
だから､ メインのソースファイルが生成されるのですが､ それは空っぽなんです｡
printfを取り除き､ コードを書き始めましょう｡
standard bullというファイルを入れます｡
私はまだこれをやっていません｡ ブール値をアンダースコアで作成しています｡
ちょっとテストしてみましょう､ boolができるようにしたいんです｡
これでboolsが使えるようになったわけです｡
つまり､ 通常C89では､ trueやfalseを表すデータ型はアンダースコアのboolです｡
しかし､ 後のバージョンや標準のboolファイルでは､ 実際にboolを使用するための型定義があり､
値としてtrue falseを使用することも可能です｡
そこで､ まず最初に変数を作成する必要があります｡
これからカウンターを作成し､ pと名付けます｡
これは､ pから100までの数字をチェックするときのループのカウンターになります｡
これが外側のループになります｡
また､ インナーループカウンター用の変数も作成する予定です｡
ここで､ これまでのプライムを確認します｡
実は､ ここで初期化するのではなく､ ループの中で初期化するのです｡
これから素数の整数でサイズ50の配列を作成します｡
そして､ 今のところ0以外には初期化しないことにしています｡
そして､ 素数インデックスを作成します｡ これは､ すべての偶数をスキップするのに役立ちますので､
これを2に設定します｡
この変数は､ 最初の2つの数字をハードコードするため､
正しいインデックスで開始することを確認するためのものです｡
まずはそこからですね｡
最初の2つの素数をハードコードします｡
つまり､ このように配列にアクセスすることができるのです｡
10行目で配列の作り方はわかっています｡ データ型と名前を指定し､
角括弧の中でサイズを指定するだけです｡
そして､ すべてを0に初期化します｡ これはC99の特徴で､
私たちができることです｡
また､ 配列にデータを割り当てるには､ 配列名とインデックス値を言うだけでいいんだ｡
配列は0ベースであることを忘れないでください｡
だから､ プライムサブ0と言うことになる｡
そして､ 最初のプライムは2になる予定です｡
2は最初の素数である｡
2番目の素数は､ 3に等しくなる｡
このようにして､ 私はいくつかの素数を手に入れ､
以前にテストして､ さらに素数を見つけることができるのです｡
そして､ いよいよルーピングです｡
5から100までのすべての数字を通過させる外側のforループが必要です｡
4が素数でないことは分かっているので､ 5からでいいんです｡
つまり､ 4 pイコール5､ pは100以下､ そして偶数を飛ばすと言うことができるのです｡
だから､ pはp＋2に等しいと言うことになる｡
数字を見る必要はありません｡ これは外側のループになります｡
そして､ 繰り返しになりますが､ テストをしながら進めていくことです｡
ここで､ 素数を見つけたかどうかを示すブール変数も設定する｡
そこで､ ここでboolが使えるようになり､ ローカル変数Boolean
is primeを作るだけです｡
なぜなら､ 以前に生成された素数のリストをすべて調べたとき､ あるいは最新の素数にたどり着き､
それが平方根でないことを確認したときだけ､
この値をfalseに設定するつもりだからです｡
つまり､ is primeは5から100までの各反復において､
2を飛ばしてtrueに等しくなる｡
さて､ 私のインナーループは､ 以前に生成したすべての素数を調べます｡
Iの平方根より大きくなっていないことを確認する｡
そこで､ すべての数字を平方根になるまで調べると､ それがxの条件となることがあります｡
また､ 素数を見つけた場合は終了します｡
つまり､ is primeが真で､ 限界まで行った場合､
p÷prime sub-Iがprimes sub-I以上となる､
ということです｡
そして､ プラス・プラスIがループ制御変数です｡
これが本当にアルゴリズムの鍵なんです｡
そこで､ 偶数を飛ばして5から100までのすべての素数を求めてみることにします｡
そして内部ループでは1から始まり､
is primeをtrueに設定するか､ 終了条件であるp÷prime
sub-Iがprime sub-Iより大きくなるまでずっと進みます｡
これは本質的に､ 平方根を見つけるときに終了します｡
もしこれがループなら､ ループの内部で実際に素数をチェックすることになります｡
数字が素になる方法は､ 数字で割るんです｡
そして､ 0がなければ問題なし｡
だから､ p mod prime sub-I equals equals 0をすればいいんです｡
そして､ もしそれが本当なら､ 素数は存在しないことになる｡
だから､ Booleanをfalseに等しく設定することができるのです｡
というのも､ 私たちがやっているのはブール値をfalseに設定することだけだからです｡
そして､ 素数は見つからなかったので､ pを素数配列に追加する必要はないことを教えてくれます｡
最後に､ ブール値がtrueに設定されているかどうかをチェックし､ trueに設定されていれば､
配列を埋めていきます｡
配列に追加したい｡ そこで､ プライムを見つけた配列に追加していくのです｡
だから､ 素数と言っておけばいいし､ 素数指数と言っておけばいいのです｡
なぜなら､ これは配列に入れたい場所のインデックスで表現されるもので､
つまりインデックス2である要素3から始めたいのです｡
配列の正しい位置に置くことを確認し､
pを設定します｡ なぜなら､ pは見つけた素数だからです｡
それが素数かどうかを調べているんです｡
5時からスタートです｡
もし5が素数になるのなら､ 1から始まる数字とそれ以前の素数を比較して､
0で割り切れないなら問題ない､ すべての数字についてそうしなければならない､
と｡
そして最後に､ このプライム・インデックスをインクリメントするのです｡
だから､ 次に素数を見つけるときは､ 正しいインデックスになるんだ｡
そして､ それだけです｡
そして､ これが素数を求めるアルゴリズムの全てである｡
だから､ それを保存し､ 構築し､ すべてがうまくいくようにしたいのです｡
私たちは大丈夫です｡
だから､ 私は標準のboolを含むことによって､ 真のfalse値を追加するのが好きです､
それを忘れないでください｡
そして最後に､ 素数をプリントアウトするだけです｡
だから､ 単純なforループを用意すればいいんです｡
そして､ すべて同じ行にプリントするため､ 改行は入れません｡
そこで､ ループ制御変数を0
Iに再定義します｡
配列のすべてのサイズを表す素数インデックスまで行き､
それを1行でプリントアウトします｡ パーセントIまたはdと素数サブIです｡
そして､ 一番最後に改行を入れます｡
セミコロンでそんな感じ｡
しかし､ 改めてこの番組で気づくことがあります｡
まず､ インデント（字下げ）に注目してください｡ すべてのブロックがインデントされています｡
ブロックの中に複数のステートメントがある場合､ 括弧を使うこともありますが､
使わないこともあります｡
この25行目のif文では､ 括弧を使っていません｡
Forループは､ もうすっかりおなじみになりましたね｡
この課題で得たいのは､ 本当に配列です｡
そこで､ primesという配列を作成し､ サイズを50に設定し､ すべてを0に初期化します｡
そして､ 最初の2つの要素に2と3をセットして､
19行目から32行目までのこのアルゴリズム全体が､ 前の素数での配列を見て素数かどうかを判断しているのです｡
あと､ 平方根より大きいときに飛び出す｡
ここでも角括弧をたくさん使って配列にアクセスしたり､ 配列に値を代入したりしていますが､
これはとても簡単なことです｡
では､ これを作って見てみましょう｡
警告もエラーもない｡
これを実行すると､ 出力されるのは100までのすべての素数 2 3 5
7 11 13 17 19 23 29 31 37 41 43 といった具合になります｡
それらはすべて素数である｡
そして､ 素数とは､ 自分自身の因数だけであったものです｡
他の数で割っても余りは出ない｡
つまり97は1と97の2つの要素しかないんです｡
このように､ 今回もちょっとしたクイックプログラムになっています｡
解決策を提供します｡
分析することができます｡
しかし､ 重要なポイントは､ 配列と､ 私が使用した標準的なboolについてです｡
このboolは､ アンダースコア大文字のbなしでブール型データ型を作成でき､
1や0ではなく､ 真の偽の値を使用することができます｡
お役に立てれば幸いです｡ ありがとうございます｡