輝々凛々

ガンバるってことは、素晴らしい事だ。

デザインパターン「最大値パターン」

この間、人にプログラムを説明していて気づいたんですけど、
プログラミングには「最大値パターン」ってのがあると思います。
(ま、enumerator/iteratorパターンと言うのが普通ですが。
 英語じゃ意味わかんないっしょ?)

あのデザインパターンと同じですが、こっちはもっとプリミティブ。

ある配列から最大値を求める


普通ですね。こんな感じ↓


max = 0;
for (i = 0; i < 10; i++) {
  if (array[i] > max) {
    max = array[i];
  }
}



ある配列から最高の答えを求める


さっきのは、配列の中で大きい数字を求めるというものでした。
今度は、「大きい数字」という部分を「最高の答え」と抽象化します。
たとえば「より小さい数字=最高の答え」とすると、こんな↓感じ。


min = 0;
for (i = 0; i < 10; i++) {
  if (array[i] < min) {
    min = array[i];
  }
}



もっと例。たとえば「より配列の後ろにある偶数=最高の答え」なら↓


answer = 0;
for (i = 0; i < 10; i++) {
  if (array[i] % 2 == 0) {
    answer = array[i];
  }
}



簡単ですよね。ようわ、if文の条件式が変わっているだけです。
ま、変数名も変わっていますが、些末なことです。


この例を見てわかるようにif文の条件式さえ変えれば、
配列中の「最高の答え」を求めることができます。
つまり。
このif文の条件式を「最高の答えか?」という関数に置き換えてしまえば
どんなに複雑な求解方法だろうが、最高の答えを導くことができます。
たとえば、こんな↓感じになります。


answer = 0;
for (i = 0; i < 10; i++) {
  /* AnswerYorimoSaikoDesuka()は、array[i]がanswerよりも
  最高の答えであるときtrueを返し、そうでなければfalseを返す関数 */

  if ( AnswerYorimoSaikoDesuka(array[i], answer) ) {
    answer = array[i];
  }
}



ある集合の中から最高の答えを求める


今までのパターンは、配列の中から答えを見つけるものでした。
だけど、当然のことながら、何も配列である必要はありません。
そういう場合は、こう↓


answer = 0;
for (hoge = 最初の要素; hogeが存在している; hoge = 次の要素) {
  /* AnswerYorimoSaikoDesuka()は、hogeがanswerよりも
  最高の答えであるときtrueを返し、そうでなければfalseを返す関数 */

  if ( AnswerYorimoSaikoDesuka(hoge, answer) ) {
    answer = hoge;
  }
}


と、こんな↑感じです。
かなり抽象的ですが、配列の場合と対応付けて読むと普通ですね。
実際、こんなコードがあるのかというと、最近のコンピュータ言語には頻繁に出てきます。
たとえば、C#では「hoge = 次の要素」という部分は「hoge.MoveNext()」と書きます。
C++では「++hoge」あるいは「hoge++」と書きます。
Javaでも大して変わりません。



まとめ


配列のような何かの要素の集合体から、ある条件下で一番良い答えを探すときは
ここで紹介した「最大値パターン」を使います。
条件をもっと複雑にすることも可能です。
たとえば、
・ある要素とその次の要素の和が最大値
・ある要素とその前後の要素の平均が最大値
・ある画像の一番白っぽい10×10ピクセル
・ある音の一番ノイズがのってる部分
などなどです。


ま、あえて今さら言う必要もないようなパターンですが
「当たり前じゃん」と思ってるパターンほど、知らない人にとっては目から鱗だと思います。
そんなわけで、ご紹介までに。


関連記事

ツッコミの投稿


(ツッコミ非公開の場合はチェック)