偶数インデックスをコピーする方法、改良、駄目出しお願いします – プログラミング – Home

偶数インデックスをコピーする方法、改良...
 
通知
すべてクリア

[解決済] 偶数インデックスをコピーする方法、改良、駄目出しお願いします


デグラフ
 デグラフ
(@デグラフ)
ゲスト
結合: 16年前
投稿: 3
Topic starter  

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;
}


引用未解決
トピックタグ
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

#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;
}


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

補足というか蛇足

> beginは常に偶数前提(想定は0)

つまり、こういうのはありえないものとして無視してます。
 std::transform(source.begin()+1, source.end(),
std::back_inserter(result), pred<T>());


返信引用
デグラフ
 デグラフ
(@デグラフ)
ゲスト
結合: 16年前
投稿: 3
Topic starter  

Banさん、お世話になります
勉強になります。ありがとうございました。
constを、外さずにmutableを使うとか、いろいろ参考になります。

>> // そもそも「インデクスを処理に使う」なら、transformなどより
>> // 普通に[]で参照した方がよほどスマートな気がしますが、
スマートさよりも、私自身、引き出しが少ないので、いろんな、パターンや考え方を、
教わりたかった次第なので、大変勉強になました。

>> // STLやalgorithmの勉強用ですか?
はい、その通りです。
>>// ちなみに、こういうことがしたいわけではないのですよね?
はい。
大変ありがとうございました。


返信引用
デグラフ
 デグラフ
(@デグラフ)
ゲスト
結合: 16年前
投稿: 3
Topic starter  

終了チェック入れ忘れました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました