N
要素のベクトルが与えられた場合v = (1, 2, 3, 4, ... , N)
サイズK<N
のすべてのチャンクにわたるリターン・レンジ・イテレータ。 N%K!=0
の場合、最後の範囲はK
より小さくなる可能性があります。例えばコンテナをチャンクに分割するC++
:
v = ("a","b","c","d","e")
表示文字列
"ab", "cd", "e"
N=v.size();
K=2;
一つの可能な解決策は、次のとおりです。
for(unsigned int i=0; i<v.size(); i+=K)
cout << boost::join(v | boost::adaptors::sliced(i, min(i+K, v.size())), "");
このソリューションはかなりOKですが、それはいくつかの問題があります。
for
ループ - それは必要ですか?min(i+K, v.size())
アルゴリズムクラッシュの代わりにi+K
を書き込む場合、境界の場合にはさらに注意を払う必要があります。これは醜く見え、気をそらす。
より洗練されたソリューションを提案できますか? エレガントなソリューションとは、一般的なアルゴリズムを使用することです。一般的なライブラリ(boostなど)を使ってビルドするか、提供します。
-------------------------- [編集] ----------------- ---------
あなたの中には実例がありましたが、ここはそうです。
#include <iostream>
#include <vector>
#include <string>
#include <boost/range/adaptor/sliced.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/assign.hpp> //just for fun
using namespace std;
using namespace boost::assign;
int main(int , char **)
{
const int K = 2;
vector<string> v;
v += "a","b","c","d","e";
for(unsigned int i=0; i<v.size(); i+=K)
cout << boost::algorithm::join(
v | boost::adaptors::sliced(i, min(i+K, v.size())), "")
<< endl;
}
出力:
template <class T, class Func>
void do_chunks(T container, size_t K, Func func) {
size_t size = container.size();
size_t i = 0;
// do we have more than one chunk?
if (size > K) {
// handle all but the last chunk
for (; i < size - K; i += K) {
func(container, i, i + K);
}
}
// if we still have a part of a chunk left, handle it
if (i % K) {
func(container, i, i + i % K);
}
}
あなたは完全な例を投稿してみませんか? –
@VJovicの例で私は本当に必要なことを示しましたが、これはもっと一般的な質問です。コンテナのすべてのチャンクで別々にアルゴリズムを実行する方法です。 – bartek
残念なことに、私はあなたの例をコンパイルできず、私はクリスタルボールを失った;) –