問題CPP02104の解答例と解説 C++ Lv.3

vector<int> 偶数の総和(15分)


前の問題の解答例と解説に書いてあることは省略して説明するよ。読んでいなかったらこちらを先に読んでね。
 vector<int> 総和

<解答例 1>
F11キーでフルスクリーンモード、Escキーで元に戻ります。

前の問題と似ている問題だけど、値が2で割り切れたときだけ、足し算をすればいいよね。2で割り切れるかは、10行目のように % を使って余りがゼロになるかどうかを調べれば判定できるよね。


<解答例 2>
F11キーでフルスクリーンモード、Escキーで元に戻ります。

こちらはイテレータを使った例だよ。前の問題の解答例にあるのとほとんど同じだよ。


<解答例 3>
F11キーでフルスクリーンモード、Escキーで元に戻ります。

この解答は、Level.3 にしてはちょっと難しいかもしれない。前の問題と同じようにC++標準ライブラリのaccumulate 関数を使っているんだけど、第四引数でファンクタというものを指定しているよ。6行目に書いてあるのがファンクタなんだけど、ファンクタは構造体(またはクラス)に () のオペレータをオーバライドして作るよ。そして、そのオペレータ() を第四引数に渡すんだ。こうするとaccumulateの中で行なわれる足し算の仕方を再定義できるんだ。6行目のオペレータは accum と curr の2つの引数を受け取っているけど、accum は解答例1のsum、curr 解答例1の curr に相当するよ。つまり6行目のファンクタは偶数のときだけ足し算するというファンクタで、accumulateの第四引数で足し算の仕方を再定義をしているんだ。


<解答例 4>
F11キーでフルスクリーンモード、Escキーで元に戻ります。

これは解答例3と似ているけど、11行目の accumulate 関数の第四引数には今度は関数ポインタというものを指定しているよ。4行目から7行目までは、偶数のときだけ足し算をして、偶数じゃなかったらそのまま accum を返す関数が指定されているんだけど、この関数を使えとaccumulateに指定することができるんだ。関数名に * をつけて渡せばいいよ。

ただ、関数ポインタを使う方法は、ファンクタを使う方法よりも実行スピードが遅くなる可能性が高いので、お勧めできないよ。実は関数は呼び出しをするときに関数呼び出しの処理が発生してほんのわずかだけ時間がかかるんだ。関数を探す処理と言えばいいかな。だから関数を何万回も呼ぶと、それが蓄積されてちょっと時間がかかったりするんだ。けれどもファンクタを使うと、コンパイラは関数呼び出しのコストがない、インラインという方法でコンパイルしてくれることがあるんだ。インラインだと関数を探すみたいな処理がなくなるんだ。その代り、実行ファイルのファイルサイズが大きくなる傾向があるんだけど、それでもファンクタを使った方が実行速度が速くなるんだ。


ファンクタと関数ポインタ、インラインとファイルサイズの関係は初めての人にはとても難しくて、ここだけでは理解できなくても全く問題ないよ。今はこういうものがあるんだと知っておくだけでいいし、興味があれば、どこか別のところでしっかり勉強すればいいよ。




初めての方へ:このページは、このサイトで用意しているプログラミング問題の解答と解説のページです。このサイトではブラウザ上からプログラミングができます。会員登録(無料)して、プログラミングしてみませんか?
新規登録



ログイン
メールアドレス:

パスワード:



パスワード紛失

新規登録