VC++ 2005
よろしくおねがいします。
添字が偶数のときだけ、コピーを行う、テストプログラムを下記のように書きました
ご覧の通り、偶数番目の要素のコピーを行うのに、わざわざ、同じ型の配列を準備してい
ます、なんとなく冗長に思えるのですが、改良点、transform()関数にこだわらず、他の
方法、駄目出し、などございましたら、教えてもらえないでしょうか。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef vector<int> VECTOR;
int IsEven(int n, int m);
int main() {
VECTOR rhs, lhs, result;
for(int i = 0; i < 10; ++i)
{
rhs.push_back(i); // rhsは、コピーを行う条件(添字が偶数、奇数の判定)
lhs.push_back(3); // コピーしたいデータ
}
VECTOR::iterator iter = lhs.begin();
transform
(
rhs.begin(),
rhs.end(),
lhs.begin(),
back_inserter(result),
IsEven
);
VECTOR::iterator it = result.begin();
while( it != result.end() )
{
cout << *it << endl;
++it;
}
return 0;
}
int IsEven(int n, int m)
{
return n % 2 ? 0 : m;
}
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
/// 呼び出し毎にtrue/falseが変わるだけ.
template<class T>
struct toggle : public std::unary_function<T, bool>
{
bool operator()(T=0)const { even_ = ! even_; return even_; }
/// @param[in] init 初回値
explicit toggle(bool init=true) : even_(! init) {}
private:
mutable bool even_;
};
/// lambdaとか使えると便利なのですが、とりあえず.
template<class T>
struct pred
{
T operator()(const T& t)const { return condition_() ? t : 0; }
private:
toggle<T> condition_;
};
/// 出力用ユーティリティ
template<class T> inline void
dump(const T& container, const char* const message=")
{
std::cout << message << std::endl;
for(typename T::const_iterator itr = container.begin(),
end=container.end(); itr != end; ++itr)
{
std::cout << *itr << std::endl;
}
}
/// 偶数か?
template<class T> inline bool is_even(const T& t){ return (t % 2) == 0; }
int
main()
{
typedef int T;
typedef std::vector<T> Vector;
Vector source;
for(int n=0; n < 10; ++n) source.push_back(n+100); // 適当
dump(source);
// そもそも「インデクスを処理に使う」なら、transformなどより
// 普通に[]で参照した方がよほどスマートな気がしますが、
// STLやalgorithmの勉強用ですか?
{
Vector result;
for(std::size_t n=0, max=source.size(); n < max; ++n)
{
result.push_back(is_even(n) ? source[n] : 0);
}
dump(result, 正攻法);
}
// もしもfunctorの引数がiteratorならば、
// 例えばsource.begin()からのstd::distanceなどでインデクスを取得可能です.
// (毎回std::distanceを呼ぶのが実用的かと聞かれれば、私は否といいますが)
// しかし、algorithmのfunctorは値をとりますので、そういうこともできません.
//
// std::vectorの値からインデクスを取るのは結局のところ検索です.
// 提示例(値は全て3)の場合などは判断できないでしょうし、
// 仮に別ルールがあって検索できたとしても、その検索コストはただの無駄では?
// 「偶数回目だけ処理」という話であれば、例えばこんなの(↓)もありかと思いますが…
// ※以下はともに「呼び出し回数」しか見ていないので、beginは常に偶数前提(想定は0)
{
Vector result;
std::transform(source.begin(), source.end(),
std::back_inserter(result), pred<T>());
dump(result, transform版);
}
{
Vector result;
std::remove_copy_if(source.begin(), source.end(),
std::back_inserter(result), toggle<T>(false));
// ちなみに、こういうことがしたいわけではないのですよね?
dump(result, おまけ?);
}
return 0;
}
補足というか蛇足
> beginは常に偶数前提(想定は0)
つまり、こういうのはありえないものとして無視してます。
std::transform(source.begin()+1, source.end(),
std::back_inserter(result), pred<T>());
Banさん、お世話になります
勉強になります。ありがとうございました。
constを、外さずにmutableを使うとか、いろいろ参考になります。
>> // そもそも「インデクスを処理に使う」なら、transformなどより
>> // 普通に[]で参照した方がよほどスマートな気がしますが、
スマートさよりも、私自身、引き出しが少ないので、いろんな、パターンや考え方を、
教わりたかった次第なので、大変勉強になました。
>> // STLやalgorithmの勉強用ですか?
はい、その通りです。
>>// ちなみに、こういうことがしたいわけではないのですよね?
はい。
大変ありがとうございました。
終了チェック入れ忘れました。