2017-01-15 6 views
0

マップのキーをベクトルのインデックスにマップする関数key_to_indexがあるとします。例を挙げてみましょう。キーからインデックスへのマッピングが与えられたマップからベクトルへの値(mapped_type)のコピー

std::map<int, int> source = {{1,55}, {4, 20}, {6, 25}}; 
std::vector<int> target; 

int key_to_index(int key) {return key;} 

STLアルゴリズムを使用する次のループのバージョンは?とにかく

std::vector<int> target; 
target.resize(transformed.rbegin()->first + 1); 

std::for_each(std::cbegin(transformed), std::cend(transformed), 
     [&target](const auto& e) { 
      target[e.first] = e.second; 
     } 
); 

wandbox example

:ターゲットを

std::map<int, int> transformed; 

std::transform(std::cbegin(source), std::cend(source), 
     std::inserter(transformed, transformed.end()), 
     [](const auto& e) { 
      return std::make_pair(key_to_index(e.first), e.second); 
     } 
); 

をそして埋める:

for (const auto &el: source) { 
    int index = key_to_index(el.first); 
    if (index > (int)target.size() - 1) target.resize(index + 1); 
    target[index] = el.second; 
} 
+0

'key_to_index()'関数は本当に 'key'と' index'を返すはずですか? – Galik

+0

@Galik OPは、デモンテーションの目的で自明のアイデンティティ機能を作ったと言っていました。実際の実装は重要ではありません。 –

+0

あなたは 'std :: transform'にラップしてラムダを使うことができますが、それ以外のところはそのまま残しておきます。 – DeiDei

答えて

1

基本的には、変換キーで同じ値を格納する新しいマップを作成することができます私は最初のバージョンが優れています。 STLがコードをより効率的に、あるいはより読みやすくするとは限りません。

+0

私はそれが元のコードよりも短くなることを望みました...そして、私は間違いなく、STLを使用しているバージョンがオリジナルより効率が悪いとは思わないと思います。 – AlwaysLearning

+1

@AlwaysLearningときどきSTLを避けるほうがいいです:) –

+0

@EdgarRokyan Blasphemous comment!いいぞ! – DeiDei

3

@エドガー回答は良いですが、私は第2のマップ作成が嫌いです。 key_to_indexがかなり速いと仮定すると、変換されたインデックスを持つマップを作成するよりも2倍以上実行する方が良いでしょう。

あなたのコードの明確な最適化(key_to_indexが複雑すぎる場合を除き)は、複数のサイズ変更を避けることです。そして、あなたはあなたの配列を変異させるstd::pair<int,int>operator=の値の型を持つstd::insert_iteratorに非常によく似た出力イテレータを、作成することができます元のマップ

auto max = std::max_element(source.cbegin(), source.cend(), [](auto& lhs, auto& rhs) { 
    return key_to_index(lhs.first) < key_to_index(rhs.first); }); 
target.resize(key_to_index(max->first) + 1); 

std::for_each(source.cbegin(), source.cend(), [&target](const auto& e) { 
    target[key_to_index(e.first)] = e.second; }); 
+0

「私は第2の地図作成が嫌いです。ええ、私はそれも好きではありません。ちょうど私の頭に来た最初のバージョンを投稿しました。とにかく、+1: –

+0

ニース!元のバージョンよりも速いかもしれないので、これは本当に見えます。また、ループの内部で条件付きを回避します。 – AlwaysLearning

1

std::for_eachを適用します。あなたの関数はstd::transformと書くことができます。

+0

4行のコードを書き直すのはとても難しくありません。 – AlwaysLearning

関連する問題