stl sample

// logical_not単項関数オブジェクトを使用する
#include < iostream>
#include < vector>
#include < functional>
#include < algorithm>
using namespace std;

int main()
{
  vector< bool> v;
  int i;

  // vに値を格納する
  for(i=1; i<10; i++) v.push_back((bool)(i%2));

  cout << "Original contents of v:\n";
  for(i=0; i< v.size(); i++)
    cout << v[i] << " ";
  cout << endl;
 
  // logical_not関数オブジェクトを使用する
  transform(v.begin(), v.end(), v.begin(),
            logical_not< bool>()); // 関数オブジェクトを使用する

  cout << "Inverted contents of v:\n";
  for(i=0; i< v.size(); i++)
    cout << v[i] << " ";
  cout << endl;

  return 0;
}

// ベクタを降順にソートする
#include < iostream>
#include < vector>
#include < algorithm>
#include < functional>
using namespace std;

int main()
{
  vector< char> v(26);
  int i;

  for(i=0; i< v.size(); i++) v[i] = 'A'+i;

  cout << "Original ordering of v:\n";
  for(i=0; i< v.size(); i++)
    cout << v[i] << " ";
  cout << "\n\n";

  // 降順にソートする
  sort(v.begin(), v.end(), greater());

  cout << "After sorting v using greater():\n";
  for(i=0; i< v.size(); i++)
    cout << v[i] << " ";
  cout << "\n";

  return 0;
}

// count_if()の使用例
#include 
#include 
#include 
using namespace std;

// 数が偶数かどうかを判定する単項述語
bool isEven(int i) 
{
  return !(i%2);
}

int main()
{
  vector v;
  int i;

  for(i=1; i < 20; i++) v.push_back(i);

  cout << "Sequence:\n";
  for(i=0; i< v.size(); i++)
    cout >< v[i] << " ";
  cout << endl;

  i = count_if(v.begin(), v.end(), isEven);
  cout << i << " numbers are evenly divisible by 2.\n";

  return 0;
}

// 単項関数オブジェクトを使って偶数/奇数を判定する
#include < iostream>
#include < vector>
#include < algorithm>
#include < functional>
using namespace std;

// isEvenは偶数と奇数を判別する
class isEven: public unary_function< int, bool> {
public:
  result_type operator()(argument_type i)
  { 
    return (result_type) !(i%2);
  }
};

int main()
{
  vector< int> v;
  int i;

  for(i=1; i < 20; i++) v.push_back(i);

  cout << "Sequence:\n";
  for(i=0; i< v.size(); i++)
    cout << v[i] << " ";
  cout << endl;

  i = count_if(v.begin(), v.end(), isEven());
  cout << i << " numbers are evenly divisible by 2.\n";

  return 0;
}

// テンプレート版の単項関数オブジェクトを使って偶数と奇数を判別する
#include < iostream>
#include < vector>
#include < algorithm>
#include < functional>
using namespace std;

// isEvenは偶数と奇数を判別する
// テンプレート版
template < class Arg> class isEven:
  public unary_function< Arg, bool> {
public:
  result_type operator()(argument_type i)
  { 
    return (result_type) !(i%2);
  }
};

int main()
{
  vector< int> v;
  int i;

  for(i=1; i < 20; i++) v.push_back(i);

  cout << "Sequence:\n";
  for(i=0; i< v.size(); i++)
    cout << v[i] << " ";
  cout << endl;

  i = count_if(v.begin(), v.end(), isEven());
  cout << i << " numbers are evenly divisible by 2.\n";

  return 0;
}

// 関数オブジェクトreciprocalを作成する
#include < iostream>
#include < list>
#include < functional>
#include < algorithm>
using namespace std;

// 簡単な関数オブジェクト
template < class T> class reciprocal:
  unary_function< T, T> {
public:
  result_type operator()(argument_type i)
  { 
    return (result_type) 1.0/i; // 逆数を返す
  }
};

int main()
{
  list< double> vals;
  int i;

  // リストに値を格納する
  for(i=1; i<10; i++) vals.push_back((double)i);

  cout << "Original contents of vals:\n";
  list::iterator p = vals.begin();
  while(p != vals.end()) {
    cout << *p << " ";
    p++;
  }
  cout << endl;
 
  // reciprocal関数オブジェクトを使用する
  p = transform(vals.begin(), vals.end(),
                vals.begin(),
                reciprocal< double>()); // 関数オブジェクトを呼び出す

  cout << "Transformed contents of vals:\n";
  p = vals.begin();
  while(p != vals.end()) {
    cout << *p << " ";
    p++;
  }

  return 0;
}

// 二項関数オブジェクトを作成する
#include < iostream>
#include < vector>
#include < algorithm>
#include < functional>
using namespace std;

template < class T> class midpoint:
  binary_function< T, T, T>
{
public:
  result_type operator()(first_argument_type a,
                         second_argument_type b)
  {
    return (result_type) ((a-b) / 2) + b;
  }
};

int main()
{
  vector< double> v1(5), v2(5), v3(5);
  int i;

  v1[0] = 10.0;
  v1[1] = 98.6;
  v1[2] = 12.23;
  v1[3] = 88.8;
  v1[4] = -212.01;

  v2[0] = 2.0;
  v2[1] = 3.3;
  v2[2] = 4.19;
  v2[3] = 155.0;
  v2[4] = -2.0;

  cout << "Values in v1: ";
  for(i=0; i < v1.size(); i++)
    cout >< v1[i] << " ";
  cout << endl;

  cout << "Values in v2: ";
  for(i=0; i< v2.size(); i++)
    cout << v2[i] << " ";
  cout << endl;

  // v1の要素とv2の要素の間の中点を見つける
  transform(v1.begin(), v1.end(), v2.begin(),
            v3.begin(), midpoint());

  // 中点
  cout << "Midpoints: ";
  for(i=0; i< v3.size(); i++)
    cout << v3[i] << " ";

  return 0;
}

// bind2nd()の使用例
#include < iostream>
#include < list>
#include < functional>
#include < algorithm>
using namespace std;

int main()
{
  list< int> lst;
  list< int>::iterator p, endp;

  int i;

  for(i=1; i < 20; i++) lst.push_back(i);

  cout << "Original sequence:\n";
  p = lst.begin();
  while(p != lst.end()) {
    cout << *p << " ";
    p++;
  }
  cout << endl;

// p274のコード
  endp = remove_if(lst.begin(), lst.end(),
                   bind2nd(greater(), 8));
// p275のコード 
//  endp = remove_if(lst.begin(), lst.end(),
//                 bind1st(greater(), 8));

  cout << "Resulting sequence:\n";
  p = lst.begin();
  while(p != endp) {
    cout << *p << " ";
    p++;
  }

  return 0;
}

// not1()の使用例
#include < iostream>
#include < vector>
#include < functional>
#include < algorithm>
using namespace std;

int main()
{
  vector< char> v;
  int num;
  int i;

  for(i=0; i<26; i++) v.push_back(i+'A');

  cout << "Sequence contains:\n";
  for(i=0; i < v.size(); i++)
    cout << v[i] << " ";
  cout << endl;

  // まず、Eより後の要素をカウントする
  num = count_if(v.begin(), v.end(),
                 bind2nd(greater< int>(), 'E'));
  cout << "There are " << num;
  cout << " elements greater than E.\n";

  // 次に、E以前の要素をカウントする
  num = count_if(v.begin(), v.end(),
                 not1(bind2nd(greater< int>(), 'E')));
  cout << "There are " << num;
  cout << " elements not greater than E.\n";

  return 0;
}


// シーケンスを降順にソートするもう1つの方法
#include < iostream>
#include < vector>
#include < algorithm>
#include < functional>
using namespace std;

int main()
{
  vector< char> v(26);
  int i;

  for(i=0; i< v.size(); i++) v[i] = 'A'+i;

  cout << "Original ordering of v:\n";
  for(i=0; i< v.size(); i++)
    cout << v[i] << " ";
  cout << "\n\n";

  // 降順にソートする
  sort(v.begin(), v.end(), not2(less< char>()));

  cout << "After sorting v using not2(less< char>()):\n";
  for(i=0; i< v.size(); i++)
    cout << v[i] << " ";
  cout << "\n";

  return 0;
}

// 関数アダプタを使用する
#include < iostream>
#include < vector>
#include < algorithm>
#include < functional>
#include < cstring>
using namespace std;

int main()
{
  vector< char *> v;
  vector< char *>::iterator p;
  int i;

  v.push_back("One");
  v.push_back("Two");
  v.push_back("Three");
  v.push_back("Four");
  v.push_back("Five");

  cout << "Sequence contains:\n";
  for(i=0; i< v.size(); i++)
    cout << v[i] << " ";
  cout << "\n\n";

  cout << "Searching sequence for Three.\n";

  // “関数へのポインタ”アダプタを使用する
  p = find_if(v.begin(), v.end(),
        not1(bind2nd(ptr_fun(strcmp), "Three")));

  if(p != v.end()) {
    cout << "Found.\n";
    cout << "Sequence from that point is:\n";
    do {
      cout << *p++ << " ";
    } while (p != v.end());
  }

  return 0;
}

// mem_fun()およびmem_fun1()関数アダプタを使用する
#include < iostream>
#include < vector>
#include < algorithm>
#include < functional>
using namespace std;

class Test {
  int val;
public:
  Test() { val = 0; }
  Test(int x) { val = x; }

  bool showval() { cout << val << " "; return true; }
  int doubleval() { val += val; return val; }
  int addval(int i) { val += i; return val; }
};

int main()
{
  vector< Test *> v;

  // v.push_back(&Test(1));
  // v.push_back(&Test(2));
  // v.push_back(&Test(3));
  // v.push_back(&Test(4));
  // v.push_back(&Test(5));

  // --- 監修者による変更(上の5行を以下の5行に) ---
  v.push_back(new Test(1));
  v.push_back(new Test(2));
  v.push_back(new Test(3));
  v.push_back(new Test(4));
  v.push_back(new Test(5));

  cout << "Sequence contains: ";
  // showval()を使って各値を表示する
  for_each(v.begin(), v.end(),
           mem_fun(&Test::showval));
  cout << endl;

  // doubleval()を使って各メンバを2倍にする
  for_each(v.begin(), v.end(),
           mem_fun(&Test::doubleval));

  cout << "Sequence after doubling: ";
  for_each(v.begin(), v.end(),
           mem_fun(&Test::showval));
  cout << endl;

  // addval()を使って各メンバに10を加える
  for_each(v.begin(), v.end(),
           bind2nd(mem_fun1(&Test::addval), 10));

  cout << "Sequence after adding 10: ";
  for_each(v.begin(), v.end(),
           mem_fun(&Test::showval));

  // あとしまつ --- 監修者による追加 ---
  vector< Test*>::iterator it = v.begin();
  while(it != v.end()) {
    delete *it;
    ++it;
  }
  return 0;
}


// mem_fun_ref()関数アダプタを使用する
#include < iostream>
#include < vector>
#include < algorithm>
#include < functional>
using namespace std;

class Numbers {
  int val;
public:
  Numbers() { val = 0; }
  Numbers(int x) { val = x; }

  bool showval() { cout << val << " "; return true; }

  bool isPrime() {
    for(int i = 2; i<=(val/2); i++)
      if(!(val%i)) return false;
    return true;
  }

  bool isEven() { return (bool) !(val % 2); }
  bool isOdd() { return (bool) (val %2); }  
};

int main()
{
  vector< Numbers> v(10);
  vector< Numbers>::iterator end_p;
  int i;

  // シーケンスを初期化する
  for(i = 0; i<10; i++)
    v[i] = Numbers(i+1);

  cout << "Sequence contains: ";
  for_each(v.begin(), v.end(),
           mem_fun_ref(&Numbers::showval));
  cout << endl;

  // 素数を削除する
  end_p = remove_if(v.begin(), v.end(), // primes.begin(),
                    mem_fun_ref(&Numbers::isPrime));  

  cout << "Sequence after removing primes: ";
  for_each(v.begin(),  end_p,
           mem_fun_ref(&Numbers::showval));
  cout << endl;

  // シーケンスを元に戻す
  for(i = 0; i<10; i++)
    v[i] = Numbers(i+1);

  // 偶数を削除する
  end_p = remove_if(v.begin(), v.end(),
                    mem_fun_ref(&Numbers::isEven));

  cout << "Sequence after removing even values: ";
  for_each(v.begin(), end_p,
           mem_fun_ref(&Numbers::showval));
  cout << endl;

  // シーケンスを元に戻す
  for(i = 0; i<10; i++)
    v[i] = Numbers(i+1);

  // 奇数を削除する
  end_p = remove_if(v.begin(), v.end(),
                    mem_fun_ref(&Numbers::isOdd));

  cout << "Sequence after removing odd values: ";
  for_each(v.begin(), end_p,
           mem_fun_ref(&Numbers::showval));
  cout << endl;

  return 0;
}

1