Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

<numeric>数値演算アルゴリズムひとめぐり

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2015/07/09 14:00

 「複数のプロジェクトを横断した設計~実装の後方支援」という役柄の僕は、さまざまなツールやライブラリ、サンプルコードを提供することが求められます。そのため空いた時間を見つけてはいろんなライブラリの味見をし、自分の持ち駒として溜め込むことにしています。今回は標準C++ライブラリの一つ、演算アルゴリズムを集めた<numeric>のご紹介です。

目次

iota:連番を振る

 まずはとっても簡単なiota、2つのイテレータで示されたコンテナ内の各要素を連番で埋めてくれます。

list-1
int x[10];
iota(x, x+10, 0);

 これでx[0]..x[9] が 0, 1, 2, …… 9 で埋まります。第3引数が最初の値ですから、iota(x, x+10, 4)なら4, 5, 6, ……で埋まりますね。

 Visual C++ 2013のiotaは、こんなコードで実装されていました:

list-2
template<class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T val) {
  for( ; first != last; ++first, ++val ) {
    *first = val;
  }
}

 ということは、イテレータがさす要素の型をQとして、第3引数に与えるT valがQに暗黙変換され、インクリメント演算子++が定義されていれば、どんなものでも構わんはずです。そんなクラス:sequence(数列)を書いてみました。

list-3 sequence.h
#ifndef SEQUENCE_H_
#define SEQUENCE_H_

#include <functional>

/*
 * 数列: sequence
 */
template<typename T>
class sequence {
private:
  T val_;
  std::function<T(T)> succ_;
public:
  sequence(T val, const std::function<T(T)>& succ) : val_(val), succ_(succ) {}

  // Tへの暗黙変換
  operator T() const { return val_; }

  // 現在の値を基に次の値を作る
  sequence& operator++()    { val_ = succ_(val_); return *this; }
  sequence  operator++(int) { sequence r(*this); ++(*this); return r; }
  
};

#endif

 sequenceのコンストラクタには、初期値と(++されたときに)現在の値を基に次の値を返す関数オブジェクトを与えます。

list-4
vector<int> data(10);
// 等差数列: 2, 4, 6, 8, 10, ……
iota(begin(data), end(data), sequence<int>(2,[](int x){return x+2;}));
for ( auto item : data ) cout << item << ' '; cout << endl;
// 等比数列: 1, 2, 4, 8, 16, ……
iota(begin(data), end(data), sequence<int>(1,[](int x){return x*2;}));
for ( auto item : data ) cout << item << ' '; cout << endl;

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • επιστημη(エピステーメー)

    C++に首まで浸かったプログラマ。 Microsoft MVP, Visual C++ (2004.01~) だったり わんくま同盟でたまにセッションスピーカやったり 中国茶淹れてにわか茶人を気取ってたり、 あと Facebook とか。 著書: - STL標準講座 (監修) -...

All contents copyright © 2005-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5