2016-05-19 10 views
1

my answer hereを改善する方法を見つけようとしています。私は入力コンテナを分割したいと思います。fooをのサイズがSTEPvectorにします。STEPの要素が残っていれば、vectorの最後のサイズは小さくなります入力コンテナ、この分割コンテナbarを呼び出してみましょう。イテレータを1回だけ移動する

私は入力または出力範囲を何度も繰り返したくないです。私が解決しようとしている問題の要素は単純です:

    min(STEP, distance(it, foo.end())
  1. コンテナを構築した後advance(it, size(bar.back()))からitポイントをお持ちの大きさの構築vector
  2. このvector工事を行いますと
  3. 追加barインプレース

この問題の境界への私の答えの翻訳は:

auto it = cbegin(foo); 

for (auto i = size(foo); i > STEP; i -= STEP) { 
    bar.push_back(decltype(bar)::value_type(STEP)); 
    for (auto internalIt = bar.back().begin(); internalIt != bar.back().end(); ++internalIt, ++it) { 
     *internalIt = *it; 
    } 
} 
bar.push_back(decltype(bar)::value_type(it, cend(foo))); 

問題は、この行です:bar.push_back(decltype(bar)::value_type(STEP))私はvectorを割り当て、それはコンポーネントです0初期化しています。これを行うためのよりよい方法はありますか?それでは、入力と出力の範囲を一度しか反復しないでください。

答えて

1
bar.push_back(decltype(bar)::value_type{}); // or bar.resize(bar.size() + 1); if you prefer 
bar.back().reserve(STEP); 
while (bar.back().size() < STEP) { 
    bar.back().push_back(*it); 
    ++it; 
} 

それは何を保つために必要なことはそうあなたがstd::back_inserterを使用して(ループの代わりにそれを使用することができ、高度な入力イテレータのときstd::copy_nは、高度な出力イテレータを返すことを不運のストロークです宛先イテレータを取得する)。

bar.back().size()のパフォーマンスが懸念される場合は、カウンタ変数を自由に使用してください。

+0

LOL、私は実際に自分のコードで 'copy_n'を持っていました。私はそれを見て、イテレータを価値によって理解するまで、私の入力イテレータが進まない理由を理解できませんでした。とにかく空の構造、スペースの割り当て、 'back_inserter'がスペース割り当てと直接割り当てによる構築よりも優れていることを示唆していますか? –

+0

OKだから私はベンチマークしました。構築、割り当て、挿入が割り当てと割り当てよりも遅いことを確認できます:http://coliru.stacked-crooked.com/a/206b8278ff67817fところで、私はColiruが何を持っているのか分かりませんが、彼らは常に1万の増分であるので結果が信頼できません。しかし、これをコピーしてローカルで実行すると、評価が確認できます。 –

+0

@JonathanMee:あなたが尋ねた意味で「良い」と言われました。結果ベクトルの 'bar'の各サブベクトルを1回しか実行しませんが、コードは2回実行されます(一度0に初期化し、割り当てます)。私は、特定の 'vector'実装のランタイムが良いか悪いかを考慮しなかっただけですが、bar.back()。size()のパフォーマンスについての私の発言はちょっと後悔していました。十分に致命的なメモリキャッシュを使用すると、キャッシュミスのコストが本当に大量になり、キャッシュを吹き飛ばすのに十分な大きさであるため、コードよりも速く実行できるようにすることができます.- –

関連する問題