我有
typedef std::vector<int> IVec;
typedef std::vector<IVec> IMat;
我想知道如何使用std算法填充IMat
,即如何使用更少的代码执行以下操作(所有IVec
具有相同的大小)?
void fill(IMat& mat){
for (int i=0;i<mat.size();i++){
for (int j=0;j<mat[i].size();j++){
mat[i][j] = i*j;
}
}
}
PS:已经有一种用常数填充矩阵的方法可以帮助我。最好使用pre-C ++ 11算法。
答案 0 :(得分:5)
最佳解决方案是您已经实施的解决方案。它利用i
/ j
作为偏移和计算算法的输入。
标准算法必须使用元素和维护计数器的迭代器。此数据镜像是问题的确定标志。但是,如果你想成为一个想象的话,它甚至可以在一条线上完成:
for_each(mat.begin(), mat.end(), [&](auto& i) { static auto row = 0; auto column = 0; generate(i.begin(), i.end(), [&]() { return row * column++; }); ++row; });
但正如所述,因为它可以做到并不意味着应该这样做。解决这个问题的最佳方法是for
- 循环。如果这是你的事情,即使在一条线上做也是可能的:
for(auto i = 0U;i < mat.size();i++) for(auto j = 0U;j < mat[i].size();j++) mat[i][j] = i*j;
顺便提一句,我的标准算法在Clang 3.7.0,gcc 5.1和Visual Studio 2015上运行正常。但是previously I used transform
rather than generate
。并且似乎有一些implementation bugs in gcc 5.1 and Visual Studio 2015具有lambda范围static
变量的捕获。
答案 1 :(得分:3)
我不知道这是否比双循环更好,但是在C ++ 11中使用STL可能的一种方法是使用两个RewriteRule ^static/(.*)$ /index.php?st=$1
RewriteRule ^content/(.*)$ /index.php?cl=$1
,如下所示:
for_each
答案 2 :(得分:3)
我想我会进一步评论Jonathan的优秀答案。
暂时忽略c ++ 11语法,并想象我们已经编写了一些支持类(现在无关紧要)。
我们可以想象出这样的代码:
auto main() -> int
{
// define a matrix (vector of vectors)
IMat mat;
// resize it through some previously defined function
resize(mat, 10, 10);
// get an object that is a pseudo-container representing its extent
auto extent = extent_of(mat);
// generate values in the pseudo-container which forwards to the matrix
std::generate(extent.begin(),
extent.end(),
[](auto pxy) { pxy.set_value(pxy.x * pxy.y); });
// or even
for (auto pxy : extent_of(mat)) {
pxy.set_value(product(pxy.coordinates()));
}
return 0;
}
以后100行支持代码(可迭代容器及其代理并不简单),这将编译和工作。
毫无疑问,聪明,有一些问题:
有时少即是多。